CakePHP 4 - How can I prohibit multiple logins?

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 :slight_smile: 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.