Laravel and Multi-Sessions from the Same Browser

laravel and multi-sessions from the same browser

Laravel Session Background

Sessions

Skip this section for a quick easy solution

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

The name specified here will get used every time a new session cookie
is created by the framework for every driver.

And even if we could pass it some dynamic value, something like:

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

"Geez, that seems like a lot of work"

"It sure is Billy, it sure is"

https://www.youtube.com/watch?v=dTxQ9yhGnAg

See the next part

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 in url that shows he want to switch accounts.

If your original 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 your cookie 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



Leave a reply



Submit