Link to home
Start Free TrialLog in
Avatar of DrDamnit
DrDamnitFlag for United States of America

asked on

Most elegant and efficient way to track "logged in" time

I am currently using cookies for authentication. I have done this on purpose so that a) remember me works, and b) I can authenticate users based on a key. But, this has a downfall - since I am authenticating a user at every page load (required for the security of this project to prevent people from accessing off limit areas), I am unsure how to gather stats like: "user X was logged in for 30 minutes today."

The current authentication scheme works like this:
1. User authenticates with a user / pass.

2. After authentication is verified, I create a token using HMAC, an encryption key, and a random number. The key is 8 characters long, and stored in the cookie $_COOKIE['current_user']. If "Remember me" is not checked, the cookie is lost, and you have to re-authenticate to get back in. If "remember me" is checked, the cookie for that user is saved, and the next time we load any page from the site, the token ("key") is used to authenticate instead.

3. When a page loads, the key is grabbed from cookies, and a database query is executed to find the user that has that matching key, and from that, the $current_user object is loaded which contains user information and permissions.

4. The token is delivered over SSL to prevent man in the middle attacks, and the key is sufficiently difficult to crack so the odds of someone getting into an account by "figuring out" the key are low. Especially since the key changes with every successful authentication. (It does not change if you authenticate based on the cookie, so remember me does work). If someone was able to gain access to a single account, elevation of privledges would also be sufficiently difficult because you would have to crack the "current" key of the admin.

This setup allows admins to sudo into other accounts for customer support issues because the admin can just lookup a user's current token in the database, and borrow it to support a customer.

it all works quite well.

The problem I have is that since I am authenticating in a "stateless" manner, I am not quite sure how to show that user X was logged in from 4:02pm to 4:15, and then was gone for 20 minutes, and then came back at 5:01pm and was active until 5:51pm.

My logs show a series of authentications, which could be used to calculate time on site, but I am wondering if there is a more elegant way.

Here is an example log showing several full sessions, and the beginning of a last session. Each line represents a page loading (remember, we authenticate every page every time). Startup is when the page load starts, and shutting down is when the user object is unset() after the page load is compelte. Some of these pages are very long with a lot of content, so they take upwards of 1-2 seconds.

2014-01-16 04:00:13     current_user    current_user starting up...
2014-01-16 04:00:13              shutting down...
2014-01-16 04:15:17     current_user    current_user starting up...
2014-01-16 04:15:17              shutting down...
2014-01-16 04:15:22     current_user    current_user starting up...
2014-01-16 04:15:23              shutting down...
2014-01-16 04:15:23     current_user    current_user starting up...
2014-01-16 04:15:23              shutting down...
2014-01-16 04:15:30     current_user    current_user starting up...
2014-01-16 04:15:30              shutting down...
2014-01-16 04:30:10     current_user    current_user starting up...
2014-01-16 04:30:11              shutting down...
2014-01-16 04:30:41     current_user    current_user starting up...
2014-01-16 04:30:42              shutting down...
2014-01-16 04:30:46     current_user    current_user starting up...
2014-01-16 04:30:46              shutting down...
2014-01-16 04:33:05     current_user    current_user starting up...
2014-01-16 04:33:05              shutting down...
2014-01-16 04:33:08     current_user    current_user starting up...
2014-01-16 04:33:09              shutting down...
2014-01-16 04:33:11     current_user    current_user starting up...
2014-01-16 04:33:11              shutting down...
2014-01-16 10:24:12     current_user    current_user starting up...
2014-01-16 10:24:13              shutting down...
2014-01-16 10:24:44     current_user    current_user starting up...
2014-01-16 10:24:44              shutting down...
2014-01-16 10:24:46     current_user    current_user starting up...
2014-01-16 10:24:46              shutting down...
2014-01-16 10:24:48     current_user    current_user starting up...
2014-01-16 10:24:48              shutting down...
2014-01-16 10:24:50     current_user    current_user starting up...
2014-01-16 10:24:50              shutting down...
2014-01-16 10:24:55     current_user    current_user starting up...
2014-01-16 10:24:55              shutting down...
2014-01-16 10:25:08     current_user    current_user starting up...
2014-01-16 10:25:08              shutting down...
2014-01-16 10:25:33     current_user    current_user starting up...
2014-01-16 10:25:34              shutting down...
2014-01-16 10:25:38     current_user    current_user starting up...
2014-01-16 10:25:38              shutting down...
2014-01-16 11:28:45     current_user    current_user starting up...
2014-01-16 11:28:46              shutting down...
2014-01-16 11:29:25     current_user    current_user starting up...

Open in new window

Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

You can't really tell "how long" someone is logged in for exactly the reasons you already know.  The only info you get is page or file requests.  It stops at that.  If they sit there looking at that last page for 14 days, you won't know anything about it.
Why not just store the access time in a db table.
<redacted>
There is no way to know if they are on the page for so many minutes, you can only know when they accessed the page - the web is stateless.
</redacted>

Oh I'm so slow typing.
ASKER CERTIFIED SOLUTION
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
They could have still popped to the shop Dave.
Suppose you could track scrolling and clicks on the page and fire off an ajax request to the server.  But it seems a bit OTT
If you think of how web stats work and count visits and uniques.  I visit may be defined by  inactivity for 1 hour.  

Page loads at 2014-01-16 04:00:13 = first sign in of the day
The next 19 or 20 page loads are within 15 minutes of each other where the last is
2014-01-16 04:33:11
Next load
2014-01-16 10:24:12 = New visit since it has been over 60 minutes since last page load.  There for make the last page load the end time of the the visit and the 2014-01-16 04:00:13 the start time.  

Keep a table of logs with one row of data for start and end of visit.  New row of data after 60 minutes.
Yes, Cathal, any version of this really only checks what they computer last did.