Solved

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

Posted on 2014-01-17
7
190 Views
Last Modified: 2014-02-15
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

0
Comment
Question by:DrDamnit
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 39789466
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.
0
 
LVL 58

Expert Comment

by:Gary
ID: 39789472
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.
0
 
LVL 83

Accepted Solution

by:
Dave Baldwin earned 500 total points
ID: 39789473
I'll amend that slightly.  Facebook pages run a javascript timer that checks the server for new info every minute or two.  If you want to include something like that on ALL of your pages, you can get a more precise idea of how long they are "logged in".  Or at least keeping your page in their browser window.
0
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

 
LVL 58

Expert Comment

by:Gary
ID: 39789482
They could have still popped to the shop Dave.
0
 
LVL 58

Expert Comment

by:Gary
ID: 39789489
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
0
 
LVL 53

Expert Comment

by:Scott Fell, EE MVE
ID: 39789531
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.
0
 
LVL 83

Expert Comment

by:Dave Baldwin
ID: 39789580
Yes, Cathal, any version of this really only checks what they computer last did.
0

Featured Post

Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question