views:

283

answers:

3

You would think it would be a fairly straight-forward problem, but I'm struggling a bit with designing a feature to store the last logon date / time in an ASP.Net (MVC) application.

My first instinct was to simply store the value in the database against the user's profile record and update the value to the current date/time on successful login. Of course, as soon as I record that value, all pages will display the date and time of this session's successful logon.

Plan B: A field to record the previous session and one to record this session. On logon, save this session's date/time to the "current" field and move the value previously found there into the "previous" field (obviously). It is this field that provides my "last logged in on" value.

Is this the best approach or can it be done more elegantly?

+1  A: 

There are a couple other ways you could do this...

  1. Instead of having a column on the user's record, you could have a separate table that logs everyone's logins. This would also grant you the ability to have a "show last 5 logins" feature if seeing the last login date is important or to keep statistics on login data for reporting later on. (This would build up data over time and would probably need some sort of cleanup routine or schedule script.)

  2. The global.asax has a Session_End event (or something like that). When the user first logs in that value could be stored in a session variable, then when Session_End fires it's written to the database. This method would probably end up causing more oddities than it's worth, as you'd always wonder what happens if the Session_End doesn't fire, or if the user re-logins before Session_End fired for the first login.

  3. It's been a while, but there was a sort of middleware that asp.net let you inherit from a base class and implement code that handles pre or post session begin/end. I haven't done ASP in a while so I'm rather hazy on this.

T. Stone
Session_end only works when storing your session state in proc. That is something to bear in mind. For that reason I never use it.
RichardOD
+3  A: 

Another approach is to, when logging in, read the last login date/time from the user record and save it into the session or a session cookie. Then update the user record with the current date/time. Then on your pages read the value stored in the session/cookie.

The old time will be removed when the session expires which is usually when a user needs to re-login anyway. It also has the advantage of speed and caching as it is reading from the session/cookie.

But it depends on your setup and app whether this is possible for you.

UPDATE

Just to be clear... The current date/time is persisted to the database user table every time the user logs in. But before the date/time is written to the user table, the existing value is read and saved to the session or cookie. You then update the date/time value in the user table with the current timestamp.

If your authentication ticket lasts longer than the session then use the cookie method and set the expiry of the cookie to the same expiry of the authentication ticket.

David G
No, that won't work because if the user just closes the browser without logging out (i.e. destroying the authentication ticket) the database won't be updated.
Phil.Wheeler
This would be how I would approach this problem
Chuck Conway
That will only keep the information on the client. If the user logs in from home and from work, then the information will be incorrect.You need to persist this information on the server.
Heiko Hatzfeld
This doesn't need to persist on the server, because it's semantically identical. Upon login the only information which is interesting is the previous login which is always there - no matter which approach you take.
hurikhan77
@Heiko Hatzfeld - I think you mis-read it. The date/time of each login is saved into the user record each time the user logs in.
David G
@Phil.Wheeler - Then you just need to use the cookie method with the expiry of the cookie as the same expiry of your authentication ticket. When it expires the user will need to re-login and thus create a new last login date/time cookie. Adjust the patter as needed.
David G
@DaveG - I see what you're doing. That makes sense and would likely work.
Phil.Wheeler
A: 

How about creating a custom serializable class that implements this functionality?

Such a class could simply be serialized/deserialized as a blob to the user's profile. Unless you need to be able to query on the last logon date, this could be a good solution.

My first thought was to simply use a Stack<T> to implement this, but although it is serializable, it provides no hooks that will automatically evict old values.

Mark Seemann