Sinatra / Warden / Ruby - How do I ensure that my users can only log in with a single session?

424 Views Asked by At

It's a requirement of the site I am building that users may only be logged in with a single session at a time. Should a user attempt to log in to the site from a different browser or machine while currently logged in, their login attempt needs to be rejected.

I've considered flagging the user object in the database as being logged in but this seems brittle to me as, if the user doesn't actually formally log out then the flag persists and the user gets unfairly rejected. To manage this I have to run some sort of cleanup task at regular intervals to ensure that those flags get reset, and this can introduce all sorts of other issues.

I'm using Sinatra as a core framework and Warden as an authentication manager. Is there a 'best practice' strategy for this sort of requirement?

2

There are 2 best solutions below

2
On

Should a user attempt to log in to the site from a different browser or machine while currently logged in, their login attempt needs to be rejected.

and

if the user doesn't actually formally log out then the flag persists and the user gets unfairly rejected

are in direct conflict with each other. You have to choose which wins, the old or the new, and you've chosen the old… so there's nothing unfair there.

  • If you run a clean up then you're expiring their session, so you have to pick a time that works. This is an timeless problem for HTTP as it's a stateless protocol.
  • you could use a pseudo "forgot password" feature, where they can get an email sent to them that allows them to kick off the current user.
  • perhaps you could use websockets, which would allow you monitor the connection and kill the session if it dies at the other end. If it's still open though, you have the same choice as before.
1
On

this really is not an authentication issue, but a "how do I handle what happens when an authenticated user tries to login when they are already logged in" -- so you need to answer that question first. What do you want to do when someone is already logged in? Give the newest session priority? That is, kick the older session by the same user off?