Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

whitea2's avatar

Session expiry prevents logout if remember cookie exists

The remember token allows the user to authenticate without entering credentials indefinitely (i.e. 5 years) or until the user logs out.

However, if a session expires (can test with session lifetime of 1), then the user clicks log out, the remember cookie seems to log the user back in and the session is regenerated. So, on an expired session, if there is a remember cookie present, logging out does not remove the remember cookie.

Is this working as intended?

It doesn't seem right that a user could click 'logout' after the session expires and the result is that the user's session is refreshed and the remember cookie is not removed.

Any suggestions on how to avoid this?

0 likes
12 replies
jlrdw's avatar

Logging out according to docs should log them out, but all has to be set up correctly, re-read: https://laravel.com/docs/5.4/authentication#remembering-users

If it isn't working after following the docs exactly, time to create an issue.

Remember to run php artisan cache:clear as well as other clear commands after code change.

1 like
whitea2's avatar

Thanks @jlrdw, it does log them out if the session is not expired.

I've followed the docs closely for my project so I don't think I've diverged. Maybe I'll create a fresh project and reproduce it before creating an issue.

Update: It seems to be an issue with Laravel. I created a fresh project, added auth, created user and logged in. I logged out to verify it worked correctly and saw the remember token get removed. I changed the session lifetime to 1, logged in, waited a minute and then logged out. This yielded a 'session expired' page so I navigated to the homepage, and unfortunately, I was still logged in and the remember token was still there.

click's avatar
click
Best Answer
Level 35

This is normal and expected behavior as far as I can understand your situation.

The thing is that as soon as you click logout you are not being logged out because you were already logged out because your session expired. So the logout method is never executed and that is why the remember cookie is still available.

1 like
whitea2's avatar

I agree that the framework is behaving as expected. However, it is a strange user experience to click 'logout' only to find you haven't been logged out and the remember cookie still exists.

Any thoughts on how to resolve that? Maybe expire the page somehow when the session expires?

jlrdw's avatar

Well it's up to a user to clear their cookies from time to time. I never use `remember me'.

whitea2's avatar

Thank you both for the advice/help.

I think the reason I am seeing this as a problem is because I auto-regenerate the expired session for the user. So, when the user clicks logout (after session expiry), it simply refreshes the page. For the user, this seems like nothing happened which is the desired behavior for all routes except logout.

I think the solution is to rework my project to just show a 'session expired page' on session expiration. Maybe I can work it to regenerate a session for all routes except logout.

click's avatar

You could also overwrite the logout method in the LoginController and clear the cookie yourself in that method regardless if the user is logged in or not.

In code it should look something like:

LoginController.php

public funciton __construct()
{
   $this->middleware('guest');
   // was: $this->middleware('guest', ['except' => 'logout']);
   // this makes sure that a guest is also able to logout
}
public function logout(Request $request)
{
    // if a user is logged in follow the default laravel logout logic
    if (\Auth::check()) {
        return parent::logout($request);
    }

    // if user is already logged out force remove the remember cookie
    $cookie = \Cookie::forget('cookie_name_here'); 

    return response()->redirectTo('/')->withCookie($cookie);
}

I did not test this and you need to set the correct cookie name.

1 like
Cronix's avatar

@m-rk You can just grab the cookie name from config.

$cookieName = config('session.cookie');
whitea2's avatar

I initially tried deleting the cookie in an overridden logout method but it didn't work. Not really sure why.

I don't have my code with me, but I believe I used the following to get the cookie name:

$cookie_name = Auth::getRecallerName();

It returned the correct cookie name but the cookie wasn't deleted. It seemed like it wasn't actually executing the logout method since the session was expired.

click's avatar

@awhite that is because of the middleware that is used. See the __construct() method in the code I used above

1 like
whitea2's avatar

Making this change

    public function __construct()
    {
        $this->middleware('guest');
        // $this->middleware('guest')->except('logout');
    }

makes logout() non-functional if session is active. I inserted a dd() at the beginning of logout() to verify it never makes it there. The page just refreshes...not sure how to find the 'guest' middleware. Maybe it's related to the RedirectIfAuthenticated middleware? Obviously I need a better understanding of how auth is really working.

whitea2's avatar

Tracked down why I encountered this issue to begin with. I was handling the expired session exception from https://laracasts.com/discuss/channels/general-discussion/crsf-checked-before-auth?page=2 like this:

    public function render($request, Exception $exception)
    {
        if ($exception instanceof \Illuminate\Session\TokenMismatchException) {
            session()->flash('expiredSession', 'null');
            return redirect()
                    ->back()
                    ->withInput($request->except('_token'));
        }

        return parent::render($request, $exception);
    }

This caused the page to simply reload when clicking logout after session expiration. Normally, the exception is thrown so a user understands they need to refresh in order to logout. Thanks everybody for the help.

Please or to participate in this conversation.