How does Laravel sanctum expire tokens?

48.8k views Asked by At

When I run $user->currentAccessToken()->delete(); the token expires, Auth::check() becomes false, what it is expected.

However, when I go to the personal_access_tokens table, the token is still there. There is no soft delete field. How does Sanctum now that the token is expired?

4

There are 4 answers

8
PatricNox On

I looked in the source code of sanctumm and it seems like it's a guard that handles it.

      if (! $accessToken ||
                ($this->expiration &&
                 $accessToken->created_at->lte(now()->subMinutes($this->expiration))) ||
                ! $this->hasValidProvider($accessToken->tokenable)) {
                return;
            }

This means that the validating token proccess looks like this:

  • Check if token is present in database
  • Check if token creation_date hasnt surpassed the expiration time
  • Check if the tokenable model matches the provider's model type
  • Check if the tokenable model supports API tokens

And upon fail, it's simply rejecting the request. Not deleting the token.

Deleting the token is however the manual way to revoke a token.

You may "revoke" tokens by deleting them from your database using the tokens relationship that is provided by the HasApiTokens trait:

0
Chatchai Siwilai On

You can set in config/sanctum.php array node expiration

/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. If this value is null, personal access tokens do
| not expire. This won't tweak the lifetime of first-party sessions.
|
*/

'expiration' => 60 * 24 * 7,
2
Joshua Etim On

As of writing this answer, the token now deletes from the database so that one is settled.

How Sanctum knows if a token is expired is pretty simple:

  • The token has a created date, call it C
  • The config data in config/sanctum.php has an expiration time, call it E
  • The current time you want to use the token is right now, call it N

To check for expiry, it subtracts N from C. If N - C is less than E, the token hasn't expired yet. If it is greater, the token is expired.

Example:

  • You created a token at 5:00 AM
  • The expiration time is set for 5 hours
  • You want to access data through the token at 8:00 AM

When you subtract 8 from 5, you get 3. That's just 3 hrs since you created the token. Not up to the 5 hrs you set.

If you were accessing data at say, 11:00 AM, then the time frame becomes 6 hrs, which is more than 5 hrs, meaning the token has expired.

1
Fred Ebho On

The code below would only return a token as valid if its last_used_at is greater than or equal to 72 hours. Just put this inside the AppServiceProvider & change the 72 to reflect the number of hours of inactivity you want it to react to.

use Laravel\Sanctum\Sanctum;
Sanctum::$accessTokenAuthenticationCallback = function ($accessToken, $isValid){
        return !$accessToken->last_used_at || $accessToken->last_used_at->gte(now()->subHours(72));
    };