laravel and multi-sessions from the same browser
Laravel Session Background
Sessions
Skip this section for a quick easy solutionIn Laravel, session cookies are created via the Illuminate\Session\SessionManager
class, namely through the buildSession
method:
SessionManager::buildSession
protected function buildSession($handler)
{
if ($this->app['config']['session.encrypt']) {
return new EncryptedStore(
$this->app['config']['session.cookie'], $handler, $this->app['encrypter']
);
} else {
return new Store($this->app['config']['session.cookie'], $handler);
}
}
In this method we can clearly see that the name of the session comes from our config\session.php
, looking in particular this line:session.php
'cookie' => 'laravel_session', # ~~ ln 121 at time of writing
Ok, but that doesn't help a lot, changing this, changes it everywhere, as noted by the comment proceeding it in the config. And even if we could pass it some dynamic value, something like:The name specified here will get used every time a new session cookie
is created by the framework for every driver.
'cookie' => 'laravel_session' . user()->id,
This creates a paradoxical, time ending, universe imploding outcome because you are requesting the id
from the user
which is accessed via the session
looked up by the cookie
name laravel_session
.. (mindblown)Let's leave SessionManager
and it's session.php
configuration alone. We can see from above that regardless of how we approach this, all our session info will be fall under that single laravel_session
key.
Guard
Maybe Guard will have some more information.Guard is your key to auth into your app, and one of the many things that makes Laravel awesome for quickly creating applications.
The method to look at is Guard::user()
.
One of the first things Guard::user()
does after some initial cache and logged out checking, is a session check.
Guard::user()
$id = $this->session->get($this->getName());
So here, Laravel is fetching the session values that match the result of getName()
- awesome - all we need to do is mod getName()
to return a value, let's take a took at that method:Guard::getName()
public function getName()
{
return 'login_'.md5(get_class($this));
}
That's pretty straight forward. $this
refers to the Guard class, so the md5 will effectively always be the same (if anyone knows the 'why' behind md5'ing the class name which would be the same each time, leave a comment). There are a few places where this should be updated, such as getRecallerName
.
So from here, you can extend the core Guard
class and splice in your getName and getRecallerName methods.
You will probably want to wrap some service provider around this, write some unit tests, possibly even overwrite the original auth manager.
See the next part"Geez, that seems like a lot of work"
"It sure is Billy, it sure is"
https://www.youtube.com/watch?v=dTxQ9yhGnAg
The quick "I just need an answer" answer
Ollie Read has already created a solution, found here:
https://github.com/ollieread/multiauth
I encourage you to have a look, especially the custom Guard
class which extends core Guard
with custom getName
methods.
Need to let users login with multiple credentials same as login with other account functionality in Gmail services- Laravel
What I wanted to do was to maintain multiple session
for a user, so he can log in with his other email-ids inside the same browser window in different tabs.
Here we go, how we can manage that and how Gmail
is managing it.
- At first you have to manage that, the
user
want to login with his other account or switch accounts. So you can show him the login page by appending any notation inurl
that shows he want to switch accounts.
login
URL is http://www.examle.com/login
then for multiple login, you can give him URL like
http://www.examle.com/u/1/login
(you can increase the number after u/
part as many times you want to switch accounts)- Then go to your
config/sessions.php
and edit yourcookie
part as follows
<?php
$user_type = ( ( !empty(request()) && (int)request()->segment(2) ) > 0 ? '_'. request()->segment(2) : '');
return [
//.....rest of array
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'. $user_type //This user_type generate various session keys for your multiple login according to generated URL
),
];
Then you have to change your all URL's as
dynamic
so that it can execute for both your normal route(without '/u/number/url' part
) and with the/u/number/url
part.Define the following variable at the top of your
web.php
/**
* Setting a variable to check if the user is logging in with first or multiple sessions
*/
$user_login = ( (int)request()->segment(2) > 0 ? 'u/'. request()->segment(2) : '' );
/**
* User attempting to login with other accounts
*/
Route::post($user_login. '/login', 'Auth\LoginController@login');
/**
* Get dashboard for filling the registeration forms
* Your entire app URL will now go like this, whether you can use it with user number or without it. It will go smoothly
*/
Route::get($user_login. '/dashboard', ['as' => 'dashboard', 'uses' => 'FormController@getDashboard']);
/**
* User attempting to login with other accounts
*/
Route::post($user_login. '/logout', 'Auth\LoginController@logout');
- This works great. Thanks everyone for the help.
Multiple sessions on the same browser for one single webapp
PHP sessions are tied to the domain name, so they will automatically have different sessions for each of your apps. You can use route-model binding with a custom resolution to determine the app based on the domain.
routes.php
Route::group(array('domain' => '{site}.com'), function() {
//routes go here
});
RouteServiceProvider (in boot
method)$router->bind('site', function ($value) {
return App\Site::where('custom_domain', $value)->first();
});
This is based on the assumption that you have a Site
model with a field in the database called custom_domain
. All of the routes available inside the group will have access to the Site
using dependency injection. You can adjust the model and field based on your app needs. You can use the model to customize the login-page for each app, and the apps will have independent sessions for each one.
I've also heard great things about the Landlord package. You use a middleware to define which Site
the user is, based on the url. Once that is set, all eloquent queries will be automatically scoped based on the site_id
in the database. So User::all()
would only return users for the current site.
Browser multiple tab session issue
Do not make branch_id globally, my suggesion is make branch_id component level, so as long as you need to pass branch_id to server you just need put it in request.
Related Topics
Symfony 3.1.5 Warning: Sessionhandler::Read(): Session Data File Is Not Created by Your Uid
The Behaviour of the or Operator in PHP
How to Put Double Quotes Inside a String Within an Ajax JSON Response from PHP
PHP Warning: Unknown: Input Variables Exceeded 1000
How to Call Curl_Setopt with Curlopt_Httpheader Multiple Times to Set Multiple Headers
Speeding Up Large Numbers of MySQL Updates and Inserts
How to Select a MySQL Database to Use with Pdo in PHP
PHP Readfile() and Large Files
How to Increase by 1 All Keys in an Array
A Better Way to Replace Emoticons in PHP
PHP Exec() Command: How to Specify Working Directory
Laravel: How to Use Multiple Pivot Table Relationships
Image Upload from iPhone Strips Exif Data
Converting PHP Array of Arrays into Single Array
How to Skip Elements in Foreach Loop