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

vincej's avatar
Level 15

Can't solve middleware problem

All I want to do is flash an error message on the login screen when the session fails. I have tried for days to get this right, and have failed. Here is the detail:

so, you are working on your app, and you step away for a while. you come back and resume work, however, now the session has timed out. So, your app puts an error message on the screen telling you your session has timed out. If you click on a link, the app sends you back to the login page, where again you will see a polite message. Every bank on earth has this feature.

So, I have got some simple middleware which will send you back to login ok, however, what I can not get is:

  1. a message on the login page with the message.
  2. a message on the current page informing the user that their session has lapsed. I have not even tried this yet, as I have failed to get #1 working. Furthermore, I expect this is a JS issue not a L11 issue.

So, if I can just get #1 issue solve, that is a a good start.

This is the code I have so far:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Session\TokenMismatchException;

class HandleTokenMismatch
{
    
    public function handle($request, Closure $next)
    {
        try {
            return $next($request);
        } catch (TokenMismatchException $e) {
            // Redirect to login page with a friendly message
            return redirect()->route('login')->with(
                'message',
                'Your session has expired. Please log in again.'
            );
        }
    }
}
<?php

use App\Providers\AppServiceProvider;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withProviders()
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        // api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        // channels: __DIR__.'/../routes/channels.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->redirectGuestsTo(fn () => route('login'));
        $middleware->redirectUsersTo(AppServiceProvider::HOME);

        $middleware->web(\App\Http\Middleware\HandleInertiaRequests::class);
        $middleware->web(\App\Http\Middleware\HandleTokenMismatch::class);

        $middleware->throttleApi();
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

Blade:

                @if(session('message'))
                    <div class="alert alert-danger">
                        {{ session('message') }}
                    </div>
                @endif
0 likes
3 replies
LaryAI's avatar
Level 58

To solve the issue of flashing an error message on the login screen when the session fails, your middleware and Blade template setup is mostly correct. However, let's ensure everything is set up properly and address any potential issues.

Middleware

Your middleware is correctly catching the TokenMismatchException and redirecting to the login page with a session message. Ensure that this middleware is registered in your app/Http/Kernel.php file, either globally or within a specific route group.

Blade Template

Your Blade template snippet for displaying the session message is also correct. Make sure this snippet is included in your login view file, typically something like resources/views/auth/login.blade.php.

Additional Steps

  1. Middleware Registration: Ensure your middleware is registered. You can add it to the $routeMiddleware array in app/Http/Kernel.php:

    protected $routeMiddleware = [
        // other middleware
        'token.mismatch' => \App\Http\Middleware\HandleTokenMismatch::class,
    ];
    
  2. Apply Middleware to Routes: Apply this middleware to the routes you want to protect. For example, in your web.php routes file:

    Route::middleware(['token.mismatch'])->group(function () {
        // Protected routes
    });
    
  3. Session Configuration: Ensure your session configuration is set up correctly in config/session.php. The lifetime and expire_on_close settings can affect session behavior.

  4. Testing: Test the middleware by manually expiring the session. You can do this by clearing the session storage or waiting for the session to expire naturally.

  5. JavaScript for Current Page Message: For displaying a message on the current page when the session lapses, you would typically use JavaScript to detect session expiration and display a message. This is more complex and involves client-side session management, which might include AJAX requests to check session status.

By following these steps, you should be able to display a session expiration message on the login page effectively. If you encounter any issues, double-check the middleware registration and ensure the session message is being set and retrieved correctly.

Snapey's avatar

Hi Vince

Token mismatch will only work on POST requests. Not on clicking links.

If you want to do it 'the way banks do it' you would need to use javascript on the client site to monitor session duration.

Laravel gives a backend solution only, to redirect to the login page when a guest user tries to access an auth protected url.

Consider using JavaScript to keep the session going when you have a form. A simple Javascript ajax call would be suffucient ever hour.

Snapey's avatar

you can create ajax request that running every 10 minutes or based on your preference and controller for that ajax request to check auth session already expired or not. If its already expired,

Thats silly. Try it, you will find that your session lifetime is extended each time you check, never expiring.

Except your session will expire because browser tabs go into a sleep mode when in the background.

Please or to participate in this conversation.