php - Laravel session regenerate() and invalidate() functions ← (PHP, Laravel)

I am implementing some custom auth functionality in to my application, which is built in Laravel v8. I have been looking at Laravel Breeze to see how it is has been implemented there.

These are the relevant functions from Laravel Breeze (https://github.com/laravel/breeze/blob/1.x/stubs/default/App/Http/Controllers/Auth/AuthenticatedSessionController.php):

class AuthenticatedSessionController extends Controller
{
    /**
     * Handle an incoming authentication request.
     *
     * @param  \App\Http\Requests\Auth\LoginRequest  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(LoginRequest $request)
    {
        $request->authenticate();

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

        return redirect()->intended(RouteServiceProvider::HOME);
    }

    /**
     * Destroy an authenticated session.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy(Request $request)
    {
        Auth::guard('web')->logout();

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

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

        return redirect('/');
    }
}

So you will notice:

  • In the store() function, which is called during Login, it does $request->session()->regenerate();

  • In the destroy() function, which is called during Logout, it does $request->session()->invalidate();

In my application custom auth code, I have applied the same implementation in my login and logout actions.

What I have found is, when I logout, it deletes the existing session file inside storage/framework/sessions but then creates another one.

Then when I login, it creates a brand new session file. This essentially means the folder gets full of session files.

Does anyone know the reason why it is implemented this way? I would have thought logout would just delete the session file without creating a new one?

Answer



Solution:

That is the normal behavior of PHP and it is not specific to Laravel.

In PHP by default, all sessions are files that are stored in a tmp directory which if you analyze the session.save_path value in php.ini file, you will see where it is. These files include the serialized session data that you access using $_SESSION keyword.

Laravel utilize basically the original session file store but acts a little bit different. Beside changing the directory they are saved, when you call the regenerate function it creates another session file and deletes the old one. You can see it the implementation Illuminate\Session\Store.php. The migrate function is used to delete the session and return new session id.

public function regenerate($destroy = false)
{
    return tap($this->migrate($destroy), function () {
        $this->regenerateToken();
    });
}

For the invalidate function it deletes the session file actually. If you inspect the implementation, the invalidate calls for migrate method, it calls a destroy method with session id as input and this function simply deletes the session file. But soon after it deletes the file, it needs to create a new session file, why? Because the logged out user needs a new session id so we can track them.

public function invalidate()
{
    $this->flush();

    return $this->migrate(true);
}

Laravel Session Cleanup

Laravel has a garbage cleanup functionality which runs randomly and deletes the session files that are not valid. What does it mean randomly? Well the cleanup operation is triggered based on a randomness and traffic. So in each request Laravel checks the odd of triggering the clean or not, and the odds are 2 out of 100 by default. This means if applications receives 50 requests, there is a high chance that it will trigger this cleanup.

So if you have a high traffic, there is a high chance that the session directory will be cleared at short intervals, which is quire cool since it always makes sure that the specified directory does not get over populated when visiting users increase.

By the way if you want to act aggressively and delete on a higher chance, you can change the lottery odds in the config\session.php file:

    /*
    |

Answer



Answer



Answer



Answer



Answer



Answer



Answer



---- | Session Sweeping Lottery |

Answer



Answer



Answer



Answer



Answer



Answer



Answer



---- | | Some session drivers must manually sweep their storage location to get | rid of old sessions from storage. Here are the chances that it will | happen on a given request. By default, the odds are 2 out of 100. | */ 'lottery' => [2, 100],

Source