After configuring Laravel multi auth (for example admin guard) logout function does not work correctly. When Admin and User are logged in the same computer (same session) and any account try to logout, both accounts are logged out. It works like that because:
//lluminate\Foundation\Auth\AuthenticatesUsers
/**
* Log the user out of the application.
*
* @param Request $request
* @return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->flush(); // this method should be called after we ensure that there is no logged in guards left
$request->session()->regenerate(); //same
return redirect('/');
}
php artisan make:auth
composer require hesto/multi-auth
Add service provider: HestoMultiAuthMultiAuthServiceProvider
Setup admin guard:
php artisan multi-auth:install admin -f
php artisan migrate
Link to the issue from my package: https://github.com/Hesto/multi-auth/issues/34
Have you tried this:
auth('admin')->logout()
auth('admin')->logout()
The issue is with the session flushing I assume?
@GrahamCampbell the issue is that once we login using multiple guards in the same browser. If we logout of one session, all auth sessions are logged out.
@srmklive
auth('admin')->logout()
is the same thing as $this->guard()->logout()
in AuthenticatesUsers and it works perfectly fine. The problem are next 2 lines were session is flushed without checking if another guards exist.
$request->session()->flush();
$request->session()->regenerate();
@GrahamCampbell Yes, its all about flushing session too early / without any checks.
I think just implement your own logout method perhaps is the simplest thing here. Changing the behaviour of the one in the core would be a breaking change.
@GrahamCampbell I dont want that change because its my imagination or personal wish. The feature doesnt work well. It is a bug and you guys can fix it realy fast adding conditions before session flush. And i dont think it could be a breaking change, that sounds like excuse.
@Hesto You need to implement your own logout method. To me, this isn't a bug in the framework itself. It is assumed(in my view correctly) that any auth functionality(login, logout) will be customized accordingly on a case-by-case basis.
@Hesto "You'll only want to use these package for local development, so you don't want to update the production providers array in config/app.php"
Does this mean that we can not use this package in production?
@natasa80 Package only generate files and setup some settings. After installation you can even uninstall package couse you dont need it anymore. There is no reason to keep it in production packages, but if you want to keep it, you can.
@Hesto Thank You!
If you have got list of all the guards (e.g. admin, member, etc) as a const
before logging out one of them you can overwrite \Illuminate\Foundation\Auth\AuthenticatesUsers::logout
and check if any other guard is logged in or not. If the guard that is going to logout is the only logged in guard, call the function in the trait, otherwise only call $this->guard()->logout()
. I've got this class and all the other guards e.g AdminLoginController
extend this:
abstract class AbstractLoginController extends AbstractAuthController
{
use AuthenticatesUsers {
logout as protected parentLogout;
}
/**
* @param $exceptedGuard
*
* @return bool
*/
protected function isAnyGuardLoggedIn($exceptedGuard = null)
{
// get all the guards except $exceptedGuard
$guards = AbstractAuthController::GUARDS;
foreach ($guards as $guard) {
if ($exceptedGuard !== null && $guard === $exceptedGuard) {
continue;
}
if (Auth::guard($guard)->check()) {
return true;
}
}
return false;
}
/**
* Overwrite logout function in trait to avoid logging out every logged in guard,
* if any of the guard logs out. If any other guard is logged in, do not flush the session,
* and only logout the guard who has requested to logout.
*
* Also If redirection path is different for any guard,
* this function can be overwritten as well, or a new function can be created
*
* @param Request $request
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function logout(Request $request)
{
if ($this->isAnyGuardLoggedIn($this->getGuardName()) === true) {
$this->guard()->logout();
return redirect('/');
}
// if no one else is logged in
return $this->parentLogout($request);
}
}
I have the same problem, there is no official solution yet?
The same here
Having the same issue here
Most helpful comment
Have you tried this:
auth('admin')->logout()