I built a CakePHP 4 application with a simple login using the Authentication Plugin following the tutorial (Quick Start - 2.x). Now I want to prevent one user from being able to log in at the same time. (For safety reasons). I store my session in the database. I cannot set a lock in the user database because the session can also expire without logging out manually.
Does anyone of you have a solution for such a case? How do I check if the user is in the DB as a session? How do I prevent multiple logins for a user?
Well first of all: Sessions are not user related, they are browser related (because Sessions are implemented via Cookies in the browser)
And the authentication plugin uses the session to store if a user is logged in or not.
https://book.cakephp.org/4/en/development/sessions.html#database-sessions
As you see here even if you put the session in the database you have no direct relation between sessions and your users
table.
I haven’t thought this all through but you need to do something like this:
- After a successfull login put a
is_logged_in => true
+ timeout_timestamp
values into extra columns in your users
table so you know if that user is currently logged in “somewhere” or not
- Then you have to implement some sort of “refresh” logic whenever a user does something on your website so the
timeout_timestamp
gets refreshed
- If the user then logs out manually remove the
is_logged_in
and timeout_timestamp
values
- If the user doesn’t log out manually then you have to put “some logic” either in the frontend or on each PHP request to handle what happens after e.g. 20min when the session has experied (delete the
is_logged_in
and timestamp again)
There are multiple ways how you can do this but as far as I know there is no “ready made solution” present for the CakePHP Authentication plugin. So you have to come up with your own implementation.
Thanks Kevin I was already thinking something similar.
I will start implementing it. I’ll get back to you later.
Another approach would be to store the user id in the session table (as an additional column to be able to do a query on the table). And in the Authentication.afterIdentify
you could check if the same user id has more than one session active. If so, you could selectively kill the other sessions for the same user.