pmelon
pmelon

Reputation: 187

How to limit users to one session with CakePHP 3?

I have auth working fine. Users can log in and out, no problem. The thing is, if users share a login, they can all be logged in at the same time as the one user. Not good.

I need to have CakePHP know when a user is logged in, which I assume is a process started using:

'Session' => [
    'defaults' => 'database'
]

As per the Sessions book page.

It's then I get lost. Unless I have missed it there is no reference to limiting users to one active session each. Has anyone come across this before and, if so, how did you work around it?

To clarity:

All sessions deleted from DB & all cookies deleted in browser = nothing set in either when visiting the /users/login page (incidentally, this has been set up as per the tutorials - nothing fancy).

Login = session set in db with id corresponding to cookie in browser. Exactly what you'd expect.

Logout (which then redirects back to login) = old session removed then replaced by another in DB and cookie. Different id. So something is picking up the expired cookie and refreshing it. Hmm.

The information held in the cookie is just the session id. In the DB it's simply:

Session id | a blob | expiry time

Upvotes: 7

Views: 1289

Answers (2)

Soup Cup
Soup Cup

Reputation: 121

I tie users to their cell phone. Every day they get a new 6 digit code via twilio sms. Makes it hard to share logins, but not impossible. Ultimately, I would like to track how many different machines a users uses per day and establish some fair use limitations. If a user uses three or four machines in a day, that's fine, but when they start using the same user id on twenty or fifty machines a day, that might be a problem.

Upvotes: 0

Farside
Farside

Reputation: 10363

I assume you save users and sessions in a database (by default in cakePHP it is named sessions).

Add an active_session field, update it upon login, check it on requests to ensure that current user session id matches the last one stored in the database.

On Login action do:

UPDATE `users` SET `active_session`='$session_id';

When user goes to a page that requires login, you search that value:

SELECT * FROM `users` WHERE `active_session` = '$session_id';

If the user signs in other place, the previous session key gets overwriten, and the SELECT above returns an empty result-set.

It's possible to clean the old session token before the update, so this way old session will be destroyed on per user basis.


Be careful, if you are using AuthComponent, it might rotate sessions itself, for more information you may find in the corresponding section of CakePHP manual.

I'd definitely go AuthComponent-way, and wouldn't re-invent the wheel in CakePHP.

Upvotes: 5

Related Questions