Show Log In user time details - c#

I need to show user log in time details.I have two table.One is UserMaster which contains UserDetails and one is UserLogInTimeDetails contains two columns UserId and LogedInTime.
When User Log in UserId and LogInTime stores in UserLogInTimeDetails.
When User Log Off I am deleting the row of that particular user from UserLogInTimeDetails.
But the problem is if an user close the browser then the details of the user in not deleted from UserLogInTimeDetails table.For which that user will not be able to log in again.
How to solve this issue?
I have googled and saw that browser close event in not possible to handle and in many places they have adviced to use onbeforeunload event which is not working for me.
Please help. I am in big trouble.

Perhaps you could get it working using Session_End in your global.asax file to remove the user when their session expires. Though I'm not 100% sure if you can get the session ID from this method. It may be within the EventArgs...
void Session_End(Object sender, EventArgs e) {
//Remove user from database here
}
Else, another way to store the data is based on last activity, so everytime the user submits a request you update the time of last activity. You could even store this with a session ID in the database along with their login time, and then be able to calculate the duration active from login time to last activity for that session;

Best way to go with this using signalR. You can track user is online or offline. based on even dispose you can track exact logout or browser close too.
Hope this will teach you something new. refer below link for a simple example of signalR.
signalR sample application for online, offline status

Is it important that the user cannot login multiple times from different browsers?
If not, a more common approach is to store a login information variable in a session variable (maybe login time, user id or something like that), and use it to verify if the user has logged in or not.
If the user close the browser the session is lost, and he must login again, but he can login as many times as he wishes from different browsers.
You can access these variables like this:
// Set it like this. Can be any type of object with login data.
Session["LoginData"] = "Hello";
// Get it like this.
string test = (string)Session["LoginData"];
Edit:
If it is important that the user must nog login multiple times, you have a much bigger problem to solve.
Maybe something like this could be the solution?
Let the browser (via ajax) ping the web server somehow, every few seconds or so (how many depends on how long you want the browser to be shut down before it is ok to login again vs. traffic)
When the server receives a ping from a certain user, stamp the date and time in a session variable.
If a browser is trying to access the web page in any way, first, check for the session and for how long time ago the last ping was done. If the session is null, or the time is more than the time between pings*2 (or something like that) the user can login again (send to login page). If the time is shorter check if the user is logged in. If he is, continue. If not, tell him he must log out from the first connection (or whatever you want).
Hope this helps!

Related

The "Logging out" event when a user closes the browser

I have a table called Eventlog, this table contains already data about user connection: when the user calls this action for example :
public ActionResult Login(string username, string password)
{
}
I test whether the user already exists on database or not
If yes, I use Session["user"] = username or
FormsAuthentication.SetAuthCookie(username, true); to set the user
session
And then I put a record on the Eventlog table : user X was connected at Y o'clock
This works fine, but I want also the information about the user logging out. I can do similar thing to the LogOff Action, I guess it is gonna work fine as well, but the majority of people don't use the logoff button, they only close the browser, how is it possible to implement the user logoff event for this situation when the user closes the browser: user X has been disconnected at Y o'clock. The Session_End() does not serve the need in this situation.
You have to accept the limitations of web technology. Once you have sent your response to the user agent, the server has no way to know what is happening with the request. The user might close the user agent gracefully. The UA might crash. The user might lose internet connection. His computer can crash. All of this can happen before the client even receives the response. This is the environment you are dealing with. Embrace it instead of fighting it.
If tracking logoff is important to you, there are several techniques you might use:
Rely on the session timeout. If you choose a timeout short enough it might be enough to meet your security requirements. I would consider this the preferred way, because it is simple and proven.
Use scripting to send a heartbeat from the UA to the server. You can use "ping" requests, long calls etc. However, be aware of the performance impact this comes with, the number of requests to the server and the complexity of the implementation.
Use an existing framework such as SignalR to establish a client-to-server connection and have the client check in to the server. This is basically the second option with less manual work for you.
All of this wouldn't let you intercept user logoff or loss of connection, but if the client stops responding you know that the connection is interrupted (in one of many possible ways). So you shouldn't register this as "user logged off", but rather as "user disconnected".
How is it possible to implement that ? checking every 1hour if the SessionId exists or not #Mehdi
If you do a post the last time the user does a new action with something like:
if(Session["UserName"] != null) {
/*Update the database with the last time that the user has performed a action*/
}
If you do every time the user goes to a new action, you will get the last time the user did something that has inpact on the server. Then you know the (not exact but a indicator) last time the user wasn't logged off.
It's not possible on the server side to know when a user closes the browser. However, you can use JavaScript to trigger on the window.close and send an AJAX call to the server, therefore recording when a user leaves. This is unreliable, however, since the user has control over browser settings, and could disable JS. It's probably the best you can do.

Duplicate Session ID

Hi I am working on Sessions and don't know whey the Session ID is created the same as the previous one.
I have a log table which tells which user has logged in, its time and stores its unique Session ID. When it log outs system checks for the Session ID n changes its status to log out.
But when user is logged in again the Session ID created is the same i don't know whats the mistake.
The Code is given below
log in cs file
HttpContext.Current.Session["user"]=user;
HttpContext.Current.Session["sessionid"]=HttpContext.Current.Session.SessionID;
when user log outs
log out cs file
HttpContext.Current.Session.Abandon();
Waiting for your help. Thanks in advance
You can use Guid.NewGuid().ToString() instead.
ASP.NET doesn't guarantee that the session id is unique beyond the lifetime of the session.
While each generated GUID is not guaranteed to be unique, the total number of unique keys >(2^128 or 3.4×10^38) is so large that the probability of the same number being generated twice >is very small. For example, consider the observable universe, which contains about 5×10^22 >stars; every star could then have 6.8×10^15 universally unique GUIDs.
You can always trust the GUID to be unique always. Thats the real purpose of GUID.
This SO Question asks about unique Id.
ASP.NET doesn't guarantee that the session id is unique beyond the lifetime of that session (ie. there's no living session with the same ID), I'm affraid. You should just use your own unique identifier if you want that functionality.
You can use GUID as suggested by Subin.
While time of creating sessions for a user, use the code below.
HttpContext.Current.Session["sessionid"]=Guid.NewGuid().ToString();
While Saving it to DB, use the reverse:
User.dbField = HttpContext.Current.Session["sessionid"]
Since the users are members on your website, they should already have a uniqueID, whether this is a email address or an Id? You can use this to make entries into the Login table.
Note: There is a caveat to this process; it will work fine if the user clicks on the logout button, you can remove the uniqueId from the Login Table or update status to logged out, whichever way you have this set up. But, if the user just closes the browser, no event will be fired to perform the same action, so the user will remain logged in.
You should also look at possible solutions for dealing with the clean up of users who have not clicked on the logout button.

ASP.NET Kill Session By Id

My application has a control of User Permissions, because not all users can access full website. At this moment, all those permissions for an specific user are stored in his session, 'cause It would be a problem for me to search at Database every Post Back.
The problem is that when I remove a permission, user can still access the page, and only when he closes the browser, the update take effect.
Is there a way to Kill an specific Application Session by the ID, forcing user to Log in again?
"Is there a way to Kill an specific Application Session by the ID, forcing user to Log in again?"
No. You can only access the Session object of the user doing the current request (i.e. yourself), not other users Session objects.
So, you need to store the id of the user somewhere else, for example in a static collection. When the user makes the next request you can check if the id is in the collection, and update the permissions or log out the user.
Another alternative would be to keep the permission objects of all currently logged in users in a static collection as well as in their Session variable. That way you would be able to change the permission object without accessing the Session object of that user.
Using static variables in a web application of course comes with the usual precautions. As multiple threads can access it, the access has to be synchonised. Also, as Alexei Levenkov pointed out, if you have multiple servers you have to keep the data synchonised between the servers.
You can write Session.Abandon(); or Session.Clear();
or Session.SessionID[int index];
store the particular user session value in this and then use Session.Abandon(); and Session.Clear();
For killing a particular session try using Session.Remove("key");
To remove a particular piece of Session, then use Session.Remove(), like this:
Session.Remove("YourKey");
Note: This removes the value and the key from Session, while you may see people use Session["YourKey"] = null; that will only remove the value, but leave the key. This may or may not be what you want, but just wanted to point out the distinction.

Options for storing user information while logged in

What are some options in regards to maintaining user data while they are logged into my mvc4 site? I am building off of the Internet Application template and right now I am using User.Identity.Name to get the logged in user's username that they used to login with. I'd like to be able to also store and access several other pieces of information about the user across every page on the site. Can I still use User.Identity somehow and apply other attributes to it? I started building a ProfileModel that I could pass to views, but then I don't believe I would be able to pass other models to those views, not sure.
I'm open to suggestions as far as persistent user data, and thank you for any help.
EDIT 1: When I say persistent, I mean while they are logged in, the data itself is already stored in an external database, so I won't be doing any writing of this information, simply pulling it from the database, then holding onto it for the duration of them being logged in.
You'll want to leverage Session for that. Consider the following code:
Session["Profile"] = profileObj;
or maybe you just want to store a string:
Session["SomeSetting"] = value;
What you need to store in Session is unclear, and effectively irrelevant, you can store anything. You can access the Session from any Controller.
Then later on you can get the value out like this:
var profile = Session["Profile"];
// if the profile variable is null then it doesn't exist in Session yet
In response to #AaronLS, Session lasts the duration of the IIS session that's created when the user first accesses the site. Do keep in mind that these sessions are reset if inactive for a period of time (I believe the default IIS timeout is 20 minutes) so you'd want to leverage the null return value to know that you need to redirect the user to the login page to login again.

How to track logout details when browser is closed explicitly without Logout using ASP.Net

I am trying to make a Login details of my users.
I am storing the following columns in a database table:
IPAddress, LoginTime, LogOutTime, LoginPlace
I can successfully get the details when user logs in and logs out manually (by clicking on Logout button)
My problem is when user does not click Logout or session expired or directly close the browser, then I am unable to track the record.
I am thinking to add code in the Session_End event in Global.asax file to track. But how could I track the session?
Is it a good solution?
Any suggestions would be appreciated.
Thanks in advance.
By putting some kind of helper method inside any controller/action called for example UpdateLastVisited?
UpdateLastVisited would look like.
UpdateLastVisited(this.User)
{
"UPDATE [dbo].[User] set LastVisited = #date WHERE Id = #userId";
AddParameters etc..
}
There are couple of things you should be keeping in mind while saving IPAddress of the user:
If you are developing this site for intranet and the users have machines which have IP Addresses dynamically assigned, your logic is bound to go wrong.
If you are developing site for Internet, the IP address that you get is that of ISP. To get around this you will have to use some sort of ActiveX (Not suggested).
If you still decide to go ahead with 2 remember you will fallback on 1 and hence 4 is the better option to go forward with.
Either don't code for web applications having dependencies on IP Address or ensure you are writing this application for Intranet and have static IP Addresses allocated to the machines.
Having said this, coming onto your actual problem of Logging out the user when the browser is closed without logging out:
Write a HTTP based web service which is part of your Web Application. Expose a web method say "Logout" and call this method using AJAX on Window.Close() event of javascript.
Incase you don't want to move forward with WebService, you could call your logout webpage from with in javascript on Window.close().
Even though you use one of above two approaches remember to have session time out on in your server side code.
I hope this helps.
But how could I track the session?
An ASP.NET Session is clearly defined as an object that is attached to a specific user:
ASP.NET session state identifies requests from the same browser during a limited time window as a session, and provides a way to persist variable values for the duration of that session.
so, by definition, when you access Session it's going to be attached to a user and ASP.NET is going to keep that in sync for you. Now, leveraging that information, I would recommend that you store what you can during Session_Start:
protected void Session_Start(Object sender, EventArgs e)
{
var session = HttpContext.Current.Session;
session["IPAddress"] = Request.UserHostAddress;
session["LoginTime"] = DateTime.Now;
// you'll need to plug in here how you're going to determine this
session["LoginPlace"] = "something";
}
and then in the Session_End you can do this:
protected void Session_Start(Object sender, EventArgs e)
{
HttpContext.Current.Session["LogOutTime"] = DateTime.Now;
// and now here you can persist those values to the database because
// the session has ended
}
and then I'm going to recommend that you do something a little different during logout. Rather than setting those values and persisting them to the database, like you say you are now, do this:
HttpContext.Current.Session.Abandon();
that will force the Session_End to raise and this will give your code some consistency. Further, it cleans up the session on the server immediately. See, when a user "logs out", unless you've actually killed their session, it's still alive on the server until it times out.

Categories