How to limit users to one session with CakePHP 3? - session

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

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.

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.

Related

How to get all login users sessions in Asp.Net Core 2.2?

I have site on Asp.Net Core 2.2 using Sessions.
Is there any way to get all users sessions, and all login users and iterate them?
Also break session for some user, if he is banned.
Simply, no. A user's authenticated state is persisted only via a local cookie on the client. There is no sort of "master list" of logged in users. However, if you like, you can create an additional table or otherwise log user logins and logouts, which you can then refer to for this information. It won't end up being totally accurate, particularly with logouts, because the user's auth could simply timeout, requiring no action that you could tie into to log that that that happened. However, if you have a known auth expiration, say 20 minutes, you can assume any login older than that time frame is no longer valid. That assumes an absolute expiration, which is the default. If there's a sliding expiration, you'll need to do even more work to keep some sort of user activity record.
Long and short, it's not trivial, but can be done if you really need the information.
As far as auto-logouts go, that merely requires invalidating the security stamp. This will effectually invalidate the user's auth cookie, forcing them to have to login again. At that point, you can check their "banned" status, however that would be done, and opt to reject their login attempt.
await _userManager.UpdateSecurityStampAsync(userId);
However, that will not take effect immediately, since the security stamp is not revalidated with each request. You can make that happen by setting the validation interval to zero in Startup.cs:
services.Configure<IdentityOptions>(options =>
{
options.SecurityStampValidationInterval = TimeSpan.FromSeconds(0);
});
However, that has a performance cost, as each request will require hitting the database to check the security stamp. You may want to set a more reasonable interval that balances wanting to logout a banned user as quickly as possible without requiring making excessive database requests.

How does sessions work together in PassportJS

I am having troubles to understand the login flow and signup flow in PassportJS and ExpressJS.What I really wanted to do is test if different sessions are being created. So I opened up a server and open two windows both at login pages. and then I log in and a session is created, but it is created for only person i.e. one who enters last, in my sessions table there is always one entry. Is this the expected behavior or is this wrong? How can I test this behavior in real time i.e. logging in 20 users and see 20 entries in my sessions table?
it depends on how you are handling sessions, most likely cookie, in which case you may need to refresh the browser, if that doesn't work. You're cookie expire date may not be set properly or you may not be deserializing properly. Read this for reference: https://scotch.io/tutorials/easy-node-authentication-setup-and-local

laravel 5 - when is a new session created?

I have changed the session driver of my app from file to database and found, that lots of sessions are inside app/storage/framework/sessions (~900) and now, in the mysql database.
When is a session created in laravel 5 ?
I thought when a new session cookie is set. Just wondering, because I think that ~200 sessions in ~ 30 min is too much . I don't have so many visitors. It almost looks as if every request makes a new session into the sessions table. I only changed the session driver. Did not change some other session option.
edit: This all is, because I wanted to build a 'n user online function' based on sessions. But with so many sessions, this would show too many users.
Laravel will create a session record for anything that hits your site. This includes automated requests like bots, uptime monitors, or other pings to your site.
It's possible to turn this off for certain page requests.

Express.js + Passport.js : How to restrict multiple login by the same user?

Passport by default allows the same user to login from multiple browsers and have unique sessions created. How can I configure it to destroy the first session when the user tries to create a second session?
Currently I'm using the 'Sessions' model to add the username to the record and upon subsequent login check by username if the sessions exists. But this increases traffic to the db. I'm thinking express must be doing it already or made to, keep the 'logged in users' information in memory so that the process can be simplified. I'd be thankful for ideas around how to achieve tweak with express for this purpose or any other workaround/suggestion.
Much thanks!
I saw that at least 4 users upvote this question, so I decided to create passport-strategy for that. The new strategy called passport-one-session-per-user. It's open source strategy you can access here: https://github.com/AminaG/passport-one-session-per-user
How to use it? add it right after session. For example:
app.use(passport.session())
var passportOneSessionPerUser=require('passport-one-session-per-user')
passport.use(new passportOneSessionPerUser())
app.use(passport.authenticate('passport-one-session-per-user'))
Not need for settings, or configuration.
How it is works?
The strategy, created an array that contain serializaed user objects, and sessionID.
Every time user logged in, the strategy check if the user already logged in. If so, it's flag the other session. The next time the user in the other session make a request, the strategy see the flag, and log the user out.
I'm thinking express must be doing it already or made to, keep the 'logged in users' information in memory so that the process can be simplified.
I believe the session model loggs the user in, and saves only that logged-in-ness in the session cookie. The server itself has no clue about who is logged in, but just checks this state in the (signed) session cookie provided by the browser.
You can write your own Passport.js strategy to handle it differently.

Zend Framework 2 session container lifetime

I'm a nowise in ZF2 and need an advise from more experienced users.
I'm developing a small shop I want to make different lifetime for session storage and cookies.
For example when user logins server sends a cookie with 3 months lifetime and creates session storage record (for user data) with lifetime 30 minutes. Having cookie and unique session record user can buy goods, comment, and view their profile with secure data (e.g. credit card number, phone, etc).
After 30 minutes of no activity session record must be deleted but cookie must be left (cookies lifetime must be 3 months). Having only cookie user can make comments but can not buy anything or view his/her profile.
So my I'm interesting how can I realize it with ZF2 ? - As I understood "remember_me_time" must be equal to "cookie_lifetime" or they can be changed to different values ?
Does ZF2 have any standard mechanism to delete a session storage after some time for single user or I have to create such mechanism by myself ?
If you're using ZfcUser (and if you're doing user authentication on ZF2 you should be) check out the GoalioRememberMe(https://github.com/goalio/GoalioRememberMe) module, it does exactly what you're looking for (Caveat: I've never actually used it myself so I can't vouch for it's efficacy or security)
I also suggest reading this response by Anthony Ferrara (#ircmaxell) to a somewhat similar question. It contains some background information on what you should and shouldn't do, and the gist of it is: don't try to keep the PHP session open that long, use a "remember me" cookie instead and build a new session from the remember-me cookie for visitors that don't have an active session.

Resources