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

goheels's avatar

Sanctum Expired Tokens

Hello,

I'm using Laravel Sanctum to register devices on my APK. Currently Ive got it set so that tokens expire every 3 months on creation to get my feet wet. I cannot find documention on Laravels website regarding Sanctum token expirations despite it being a built in feature. They advise deleting the token, which I'm not opposed. Anyhow, I can't make a request to a route protected by 'auth:sanctum' IF the token is expired. So I made a new middleware allowing expired tokens. Works great by itself, but not with both. Any advice would be greatly appreciated. I'd prefer not creating two routes.

Route::post('logout', [APKAuthController::class, 'logOut'])->middleware(['accept-expired-token', 'auth:sanctum']);

0 likes
3 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

Certainly! The issue here is that Laravel's auth:sanctum middleware will always reject expired tokens, regardless of any custom middleware you add before or after it. This is by design for security reasons. So, if you want to allow expired tokens for certain routes (like logout), you cannot use auth:sanctum on those routes.

Solution: Custom Middleware as Authenticator

Instead of stacking accept-expired-token and auth:sanctum, replace auth:sanctum with your custom middleware for that route. Your custom middleware should handle all authentication logic, including expired tokens.

1. Register your middleware in app/Http/Kernel.php:

protected $routeMiddleware = [
    // ...
    'accept-expired-token' => \App\Http\Middleware\Api\AcceptExpiredToken::class,
];

2. Update your route to use only your custom middleware:

Route::post('logout', [APKAuthController::class, 'logOut'])
    ->middleware('accept-expired-token');

3. In your controller, you can access the authenticated user:

public function logOut(Request $request)
{
    $user = $request->user(); // Provided by your middleware
    $token = $request->get('token');
    $tokenExpired = $request->get('token_expired');

    // Perform logout logic, e.g., delete the token
    $token->delete();

    return response()->json(['message' => 'Logged out successfully']);
}

Key Points

  • Do not use auth:sanctum on routes where you want to allow expired tokens.
  • Your custom middleware must handle all authentication and user resolution.
  • For all other routes, continue using auth:sanctum for standard behavior.

Summary:
You can't "skip" or override auth:sanctum's expiration check from another middleware. Instead, use your custom middleware in place of auth:sanctum for routes where you want to allow expired tokens. This keeps your logic clear and secure.

vincent15000's avatar

It's really not a goode idea to allow expired tokens.

I would do differently :

  • use a cron job to delete all expired tokens (for example one a day at midnight)

  • recreate a new token when a device doesn't have one anymore

martinbean's avatar

@goheels Why would you allow authentication using an expired token? The whole point of a token expiring is that it’s no longer valid.

If someone finds a year-old token that’s long expired, they shouldn’t then be able to actually authenticate with that old, expired token.

Please or to participate in this conversation.