Hesto / multi-auth

Laravel 5.3, 5.4, 5.5, 5.6, 5.7 multi auth package
MIT License
448 stars 146 forks source link

Laravel 5.3 logout problem with default login #34

Closed dneykov closed 7 years ago

dneykov commented 7 years ago

Hello, I think this package is great but I have one problem. I create admin guard and everything work. After that I run make:auth to use default LoginController for my users but when I login as users and logout after that it logout the admin user as well? Is that normal behave? Can I separate their sessions so when logout user the admin stays logged in? Thanks

Hesto commented 7 years ago

https://laracasts.com/discuss/channels/laravel/53-multi-auth-configuration-problem-guards-use-same-session?page=1

You have to know that the package only setting up things for you. It is possible that maybe there is the way to separete sessions but i dont know how yet.

ghost commented 7 years ago

I think the session()->flush() clears the complete session?

/**
 * 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();

    $request->session()->regenerate();

    return redirect('/');
}
Hesto commented 7 years ago

probably

ghost commented 7 years ago

If I comment it, it just logs out the current guard.

ghost commented 7 years ago

Is this a viable solution for the problem? There's still one session, but when you logout it checks how many guards are active. If none are active it flushes and regenerates the session.

/**
 * Log the user out of the application.
 *
 * @param  Request  $request
 * @return \Illuminate\Http\Response
 */
public function logout(Request $request)
{
    $activeGuards = 0;
    $this->guard()->logout();

    foreach (config('auth.guards') as $guard => $guardConfig) {
        if ($guardConfig['driver'] === 'session') {
            $guardName = Auth::guard($guard)->getName();
            if ($request->session()->has($guardName) && $request->session()->get($guardName) === Auth::guard($guard)->user()->getAuthIdentifier()) {
                $activeGuards++;
            }
        }
    }

    if ($activeGuards === 0) {
        $request->session()->flush();
        $request->session()->regenerate();
    }

    return redirect('/');
}
dneykov commented 7 years ago

@rsdrsd your solution seems to work.

Hesto commented 7 years ago

@rsdrsd well its not bad. I think i will apply it to the package next version, thanks.

ghost commented 7 years ago

Maybe it needs some refactoring?

Hesto commented 7 years ago

@rsdrsd Maybe a little bit. You can think about it. I will make a trait with this new logout method soon.

hugo411 commented 7 years ago

Hey, the solution from @rsdrsd is working but i just added

return $this->authenticated($request, $this->guard()->user()) ?: redirect()->intended($this->redirectPath());

Instead of

return redirect('/');

Because in my case the logout from admin doesn't go back to the same page as the logout from user.

bjufre commented 7 years ago

@hugo411 @rsdrsd @dneykov

I've created a pull request (#39) with multiple features, such as "domain" and Lucid architecture support. And one you may be interested on, the Logout method in a trait. So we can check in the session for activeGuards.

Also I've done it so the user can override the path to where you're redirected once logged out.

ghost commented 5 years ago

I don't understood the need for flush() and regenerate() the session. I've implemented my logout function as below and its working as expected:

    // web logout
    $this->guard()->logout();
    return redirect()->route('web.login');

    // admin logout
    $this->guard()->logout();
    return redirect()->route('admin.login');

Both used to be like the code below, causing issues with multi-auth logout:

     // web logout
     auth()->logout();
     session()->invalidate();
     return redirect()->route('web.login');

     // admin logout
     auth()->logout();
     session()->invalidate();
     return redirect()->route('admin.login');