Is this Laravel session handling inconsistency a bug? - laravel

I am using Laravel 5.5. I have configured a number of authentication guards that use the session driver. Each has a different user provider. The providers all use the eloquent driver, but each creates a different type of user, e.g. App\User\Staff, App\User\Customer.
In addition I have setup subdomain routing for each of my user types, e.g. staff.mydomain.com, customer.mydomain.com. Today I was delighted to find that if I log in at one sub domain, that information is not shared with the other domain (by default anyhow). This means that I can be logged in on one browser tab as a staff member, and on another browser tab as a customer.
Or at least that's what I thought.
This works fine with the file session driver, however was unpredictable when using the database driver. The database showed new session records for each sub-domain, as I would expect, and the session ID's were refreshed on login. When I checked the Auth::check() though, in one tab it showed correctly (i.e. logged in for one guard, and guest on the others). In the other tab it showed guest on all guards.
I tried this back and forth (file/database session driver), and the file driver was consistently consistent, and the database driver was consistently flaky. Is this a bug? Or is there something I am missing about session-based authentication and sub-domains?

After much debugging I finally sorted this out.
The sub-domains were unrelated to the problem. The problem was that I used the the default session tables produced by artisan session:table command. It creates a user_id field as an integer type. My user ID's are uuid.
I am pasting this here as a cautionary tale!

Related

Multi Tenant session management using multiple domains

I am trying to implement a feature similar to Slack where my application is a multi-tenant app, and a user can be logged into multiple accounts. Each account will be tied to a different domain. If logged into 2 different accounts, the user should be able to switch back and forth between the accounts. Also, the sessions should be managed independently. If one session expires, and the user needs to login, that expired session should not affect the other active sessions.
View Slack Image
The issue I am seeing is the different domain sessions override each other. This is a react frontend with Okta
Thanks for your time.
There are some gaps which require details, but here are few pointers that might help you.
Post authentication, you should be storing the authentication information like the session expiry, username in some form (local / session storage)
If I login to your application and choose a domain like (acme.com), the session information should be stored in a key like acme.com or hash(acme.com) so that how much ever domains, I login into, there will be unique keys to identify sessions and there will be no conflict of keys.
Once the domains are changed (like you switch workspaces in slack) there will be a new login session established (first time), which sets up the session information like described above.
For every workspace / domain change, the authentication libraries would be called and they would validate the stored session information, which gives the right data and expiry and user gets to use the application without issues.
Do share your implementation details or any issues had you implemented this solution.

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

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

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.

Does it ever make sense to have two concurrent sessions in the same browser?

I was wondering if it ever would make sense to have two concurrent sessions in the same browser? There could be two types of cases with this:
1) A user opens a browser window and logs in as user A, starting session 1. Then he opens another browser window (in the same browser) where he logs in as user A, but starts a different session, session 2.
I know that this is often not possible in many browsers, as one session cookie is set for the entire browser. However, in some browsers, it is possible to have multiple sessions in that manner.
2) This is similar to 1, except that the second time the user logs in, he logs in as user B, starting session 2. So now you have a person logged in as two users in the same browser.
Finally, allowing these things doesn't seem like the best security practice and neither does it seem to be practical. What do others think?
First thing First as the your Assumption is wrong. First of all you have to understand that when Single website is accessed from browser have single session and its not possible to simultaneously run different session of same web Browser.
It seems you have wrongly understand the working of Private Browser. Private Session are not made not to share information cookies and data with other public session and vise versa also. As soon as you close the Private Session all the Cache, Cookie and other things are deleted for forever.
I have not seen any web browser supporting the Multiple session of browser.
But an alternative approach is available i.e you have to create different Web Browser Profiles which can help you as each Profile data is maintained separately and have no conflict with other sessions.
One possible scenario currently I am facing requires allowing multiple user sessions from the same browser and I have not been able to find a proper solution for it yet.
We are using Yii framework. Currently we have two kinds of users i.e customers and admins. Both login from the same login form and use same session name and variables to store session information. Only based on type column in user table(customer or admin), the user is taken to appropriate views. In one of admin views(pages), there is an option for admin to log in as any of the users and propagate through the user's view in an iframe. The problem is that when the admin open two tabs and logs in as two different users, the session information of one overwrites the other and we start getting session related issues.
Can anyone suggest me a proper way to handle these kind of issues. I have searched a lot on trying to handle this with multiple sessions, but have not been able to find a proper solution yet.
There's nothing to "provide support for" here. One browser cannot hold more than one session, since it only holds one unique cookie per site, regardless of window. If a browser actually has a mode in which it supports holding two separate identical cookies per site, then it's the same as if the user logged on from another browser or another machine. That certainly should work; i.e. you should not try to subvert that behavior. A double session inside the same browser is then just a specific instance of this multi-session behavior, nothing special.

Resources