Skip to content

Migration from Sanctum or Passport ​

This guide covers common migration patterns. The right approach depends on whether you can issue new tokens to all clients or need to support existing tokens during a transition.

Conceptual Differences ​

AreaSanctumPassportsp-jwt-auth
Token formatHashed random stringJWT (Bearer)JWT (Bearer)
Refresh tokensNot built-inBuilt-inBuilt-in
Token storagepersonal_access_tokensoauth_access_tokenssp_jwt_access_tokens
Guard driversanctumpassportsp-jwt
ScopesAbilitiesScopesScopes
Token on user$user->currentAccessToken()$user->token()$user->token()

Quick Switch (New Tokens for All Clients) ​

If you can force all clients to obtain new tokens:

  1. Replace the guard in config/auth.php:
diff
 'api' => [
-    'driver' => 'sanctum',
+    'driver' => 'sp-jwt',
     'provider' => 'users',
 ],
  1. Update your login controller to use JwtTokenService instead of Sanctum/Passport token issuance.

  2. Update route middleware if using Sanctum's token abilities:

diff
-Route::middleware('auth:sanctum')->get('/me', MeController::class);
+Route::middleware('auth:api')->get('/me', MeController::class);
  1. Run the package install and migrate:
bash
php artisan sp-jwt-auth:install
php artisan sp-jwt-auth:keys --generate --pem
php artisan migrate

Gradual Migration (Dual Auth) ​

Support both old and new tokens during a transition period:

php
// config/auth.php
'guards' => [
    'api' => [
        'driver' => 'sp-jwt',
        'provider' => 'users',
    ],
    'legacy' => [
        'driver' => 'sanctum',
        'provider' => 'users',
    ],
],
php
Route::middleware(['auth:api,legacy'])->group(function () {
    // Routes that accept both token types
});

Once all clients have migrated, remove the legacy guard and Sanctum tables.

Passport to sp-jwt-auth Similarities ​

If migrating from Passport, the token response is intentionally compatible:

php
// Both return the same shape
TokenResponse::passportCompatible($pair);

The HasJwtTokens trait mirrors Passport's HasApiTokens:

php
// Passport
$request->user()->token();
$request->user()->tokenCan('scope');

// sp-jwt-auth
$request->user()->token();
$request->user()->tokenCan('scope');

Data Migration ​

To carry existing users forward without forcing re-login, you can issue sp-jwt-auth tokens server-side for active sessions during the migration window. This is app-specific and depends on your session/token tracking.