# Laravel Sanctum vs Passport nel 2026: Autenticazione API e Domande da Colloquio > Confronto tra Laravel Sanctum e Passport per l'autenticazione API nel 2026. Esempi pratici di codice, autenticazione SPA, implementazione OAuth2 e domande frequenti nei colloqui tecnici. - Published: 2026-07-26 - Updated: 2026-07-26 - Author: SharpSkill - Reading time: 5 min --- Laravel Sanctum e Passport rispondono a esigenze diverse in materia di autenticazione API. La scelta del pacchetto sbagliato porta a complessità inutili o a vulnerabilità di sicurezza. Questa guida analizza entrambi i pacchetti con esempi di codice pratici e domande reali da colloquio tecnico. > **Decisione Rapida** > > Sanctum gestisce l'autenticazione SPA e token API semplici. Passport implementa OAuth2 completo con authorization code, client credentials e refresh token. La maggior parte delle applicazioni necessita solo di Sanctum. ## Laravel Sanctum vs Passport: Differenze Fondamentali Sanctum fornisce un'autenticazione leggera basata su token, progettata per applicazioni first-party. Il pacchetto utilizza l'autenticazione tramite cookie di sessione per le SPA e Personal Access Token per app mobile e API semplici. Passport implementa la specifica OAuth2 completa, inclusi authorization server, client credentials grant e autenticazione machine-to-machine. Questa complessità ha senso per applicazioni che devono autorizzare l'accesso di terze parti. | Caratteristica | Sanctum | Passport | |----------------|---------|----------| | Caso d'uso principale | SPA, App Mobile, API Semplici | OAuth2 Third-Party, Machine-to-Machine | | Tipo di token | Token hash semplici | JWT con scope OAuth2 | | Auth Sessione | Sì (basata su cookie) | No | | Grant OAuth2 | Nessuno | Specifica completa | | Dimensione pacchetto | Minimale | Significativa | | Configurazione | Semplice | Complessa | ## Implementare Sanctum per l'Autenticazione SPA L'autenticazione SPA con Sanctum si basa sui cookie di sessione Laravel invece che sui token API. Frontend e backend devono condividere lo stesso dominio di primo livello affinché funzioni. ```php // config/sanctum.php return [ 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( '%s%s', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : '' ))), 'expiration' => null, // I token non scadono mai per default 'middleware' => [ 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, ], ]; ``` La SPA deve chiamare l'endpoint del cookie CSRF prima di effettuare richieste autenticate. Questo stabilisce la sessione e imposta il cookie XSRF-TOKEN. ```javascript // Frontend: Inizializzare la protezione CSRF prima del login async function initializeAuth() { await fetch('/sanctum/csrf-cookie', { credentials: 'include' }); } async function login(email, password) { await initializeAuth(); const response = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-XSRF-TOKEN': getCookie('XSRF-TOKEN'), 'Accept': 'application/json' }, credentials: 'include', body: JSON.stringify({ email, password }) }); return response.json(); } ``` ## Autenticazione con Token API Sanctum Le applicazioni mobile e le integrazioni di terze parti utilizzano Personal Access Token invece dei cookie di sessione. Sanctum memorizza questi token come hash SHA-256 nel database. ```php // app/Http/Controllers/AuthController.php namespace App\Http\Controllers; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use Illuminate\Validation\ValidationException; class AuthController extends Controller { public function createToken(Request $request) { $request->validate([ 'email' => 'required|email', 'password' => 'required', 'device_name' => 'required', ]); $user = User::where('email', $request->email)->first(); if (! $user || ! Hash::check($request->password, $user->password)) { throw ValidationException::withMessages([ 'email' => ['Le credenziali fornite non sono corrette.'], ]); } // Token con abilities (scope) $token = $user->createToken( $request->device_name, ['read', 'write'] // Abilities opzionali ); return response()->json([ 'token' => $token->plainTextToken, 'expires_at' => null // Configurare in sanctum.php ]); } public function revokeToken(Request $request) { // Revocare il token corrente $request->user()->currentAccessToken()->delete(); return response()->json(['message' => 'Token revocato']); } } ``` Le route vengono protette con il middleware `auth:sanctum`. Le abilities del token vengono verificate usando il metodo `tokenCan`. ```php // routes/api.php use Illuminate\Support\Facades\Route; Route::middleware('auth:sanctum')->group(function () { Route::get('/user', function (Request $request) { return $request->user(); }); Route::post('/posts', function (Request $request) { // Verificare se il token ha l'ability write if (! $request->user()->tokenCan('write')) { abort(403, 'Token non autorizzato alla scrittura'); } return Post::create($request->validated()); }); }); ``` ## Configurare Laravel Passport per OAuth2 Passport richiede una configurazione più elaborata ma offre funzionalità OAuth2 complete. L'installazione crea tabelle nel database per client, token e refresh token. ```bash composer require laravel/passport php artisan passport:install ``` Il comando `passport:install` genera le chiavi di crittografia e crea i client Personal Access e Password Grant. ```php // app/Models/User.php namespace App\Models; use Laravel\Passport\HasApiTokens; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use HasApiTokens; // ... } ``` Le route di Passport vengono registrate nell'AuthServiceProvider: ```php // app/Providers/AuthServiceProvider.php namespace App\Providers; use Laravel\Passport\Passport; use Illuminate\Support\ServiceProvider; class AuthServiceProvider extends ServiceProvider { public function boot(): void { Passport::tokensExpireIn(now()->addDays(15)); Passport::refreshTokensExpireIn(now()->addDays(30)); Passport::personalAccessTokensExpireIn(now()->addMonths(6)); } } ``` ## OAuth2 Password Grant con Passport Il Password Grant permette alle applicazioni first-party di ottenere token con username e password. Viene comunemente utilizzato per le app mobile. ```php // app/Http/Controllers/OAuth/TokenController.php namespace App\Http\Controllers\OAuth; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; use App\Http\Controllers\Controller; class TokenController extends Controller { public function issueToken(Request $request) { $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); $response = Http::asForm()->post(config('app.url') . '/oauth/token', [ 'grant_type' => 'password', 'client_id' => config('passport.password_client_id'), 'client_secret' => config('passport.password_client_secret'), 'username' => $request->email, 'password' => $request->password, 'scope' => '*', ]); if ($response->failed()) { return response()->json([ 'error' => 'Credenziali non valide' ], 401); } return $response->json(); } } ``` ## Client Credentials Grant per Machine-to-Machine Il Client Credentials Grant è ideale per la comunicazione server-to-server dove non è richiesta l'interazione utente. ```php // Middleware per Client Credentials Route::middleware(['client'])->group(function () { Route::get('/api/external/data', function () { return response()->json([ 'data' => ExternalData::all() ]); }); }); ``` L'applicazione client si autentica con Client ID e Secret: ```php // Servizio esterno: richiedere token $response = Http::asForm()->post('https://api.example.com/oauth/token', [ 'grant_type' => 'client_credentials', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'scope' => 'read-data', ]); $token = $response->json()['access_token']; // Chiamare l'API con il token $data = Http::withToken($token) ->get('https://api.example.com/api/external/data') ->json(); ``` ## Scope dei Token per Permessi Granulari Sia Sanctum che Passport supportano gli scope per limitare i permessi dei token. Passport definisce gli scope nell'AuthServiceProvider: ```php // app/Providers/AuthServiceProvider.php use Laravel\Passport\Passport; public function boot(): void { Passport::tokensCan([ 'read-posts' => 'Leggere i post', 'write-posts' => 'Creare e modificare post', 'delete-posts' => 'Eliminare post', 'admin' => 'Accesso amministratore completo', ]); Passport::setDefaultScope([ 'read-posts', ]); } ``` Le route possono quindi richiedere scope specifici: ```php // routes/api.php Route::middleware(['auth:api', 'scope:write-posts'])->group(function () { Route::post('/posts', [PostController::class, 'store']); Route::put('/posts/{post}', [PostController::class, 'update']); }); Route::middleware(['auth:api', 'scopes:read-posts,write-posts'])->group(function () { // Richiede ENTRAMBI gli scope Route::get('/posts/drafts', [PostController::class, 'drafts']); }); ``` ## Considerazioni sulla Sicurezza nell'Autenticazione Token La gestione sicura dei token richiede diverse misure di protezione. La rotazione dei token previene l'uso prolungato di credenziali compromesse. ```php // app/Http/Controllers/TokenController.php public function refreshToken(Request $request) { $user = $request->user(); $currentToken = $user->currentAccessToken(); // Revocare il vecchio token $currentToken->delete(); // Creare nuovo token con le stesse abilities $newToken = $user->createToken( $currentToken->name, $currentToken->abilities ); return response()->json([ 'token' => $newToken->plainTextToken, 'message' => 'Token rinnovato con successo' ]); } ``` Per una maggiore sicurezza, configurare le scadenze dei token: ```php // config/sanctum.php return [ 'expiration' => 60 * 24, // 24 ore in minuti // Rimuovere automaticamente i token scaduti 'prune_after' => 7, // giorni ]; ``` Lo scheduler può pulire automaticamente i token scaduti: ```php // app/Console/Kernel.php protected function schedule(Schedule $schedule): void { $schedule->command('sanctum:prune-expired --hours=24')->daily(); } ``` ## Domande da Colloquio sull'Autenticazione API Laravel I colloqui tecnici per sviluppatori Laravel spesso valutano la comprensione dei concetti di autenticazione. Le seguenti domande e risposte coprono gli argomenti principali. **Domanda: Quando scegliere Sanctum rispetto a Passport?** Sanctum è la scelta giusta per applicazioni first-party: SPA che girano sullo stesso dominio dell'API, app mobile sviluppate dallo stesso team e requisiti semplici di token API. Passport è necessario quando serve funzionalità OAuth2: applicazioni di terze parti che necessitano accesso, Authorization Code Flow per servizi esterni, Client Credentials per comunicazione server-to-server o rotazione dei Refresh Token. **Domanda: Come funziona il meccanismo di protezione CSRF nell'autenticazione SPA di Sanctum?** Nell'autenticazione SPA, Sanctum utilizza sessioni e cookie Laravel. Il processo inizia con una richiesta a `/sanctum/csrf-cookie`, che imposta un cookie XSRF-TOKEN. La SPA legge questo cookie e invia il valore nell'header X-XSRF-TOKEN con ogni richiesta autenticata. Laravel valida questo token contro il valore memorizzato in sessione. Questo protegge dal Cross-Site Request Forgery, poiché altri domini non possono leggere il cookie. **Domanda: Quali sono le implicazioni di sicurezza dei Personal Access Token?** I Personal Access Token funzionano come password con validità illimitata. Le misure di sicurezza includono: scope limitati per ogni token, scadenze dei token, memorizzazione sicura lato client, possibilità di revoca immediata, logging di tutti gli utilizzi dei token e rotazione regolare dei token. **Domanda: Come implementare il Rate Limiting per l'autenticazione API?** Il Rate Limiting protegge da attacchi brute-force e abuso dell'API: ```php // app/Providers/RouteServiceProvider.php use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Support\Facades\RateLimiter; public function boot(): void { RateLimiter::for('api', function (Request $request) { return Limit::perMinute(60)->by( $request->user()?->id ?: $request->ip() ); }); RateLimiter::for('auth', function (Request $request) { return Limit::perMinute(5)->by( $request->ip() ); }); } ``` **Domanda: Come testare endpoint API autenticati?** Laravel fornisce il metodo `actingAs` per i test con Sanctum e Passport: ```php // tests/Feature/ApiTest.php use App\Models\User; use Laravel\Sanctum\Sanctum; public function test_authenticated_user_can_access_profile(): void { $user = User::factory()->create(); Sanctum::actingAs($user, ['read']); $response = $this->getJson('/api/user'); $response->assertOk() ->assertJson(['email' => $user->email]); } public function test_token_without_scope_cannot_write(): void { $user = User::factory()->create(); Sanctum::actingAs($user, ['read']); // Nessuno scope 'write' $response = $this->postJson('/api/posts', [ 'title' => 'Test Post' ]); $response->assertForbidden(); } ``` ## Configurare l'Autenticazione Multi-Guard Applicazioni complesse possono richiedere più meccanismi di autenticazione simultaneamente. Laravel permette di definire guard multipli: ```php // config/auth.php return [ 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'sanctum', 'provider' => 'users', ], 'admin-api' => [ 'driver' => 'passport', 'provider' => 'admins', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], 'admins' => [ 'driver' => 'eloquent', 'model' => App\Models\Admin::class, ], ], ]; ``` Le route possono quindi utilizzare guard specifici: ```php // routes/api.php Route::middleware('auth:api')->group(function () { // Route protette da Sanctum per utenti normali }); Route::prefix('admin')->middleware('auth:admin-api')->group(function () { // Route protette da Passport per amministratori }); ``` ## Best Practice per Ambienti di Produzione Il deployment dell'autenticazione API in ambienti di produzione richiede considerazioni aggiuntive. HTTPS è obbligatorio per tutte le richieste che trasmettono token. Le variabili d'ambiente devono memorizzare le configurazioni sensibili. ```php // .env SANCTUM_STATEFUL_DOMAINS=app.example.com,api.example.com SESSION_DOMAIN=.example.com # Passport PASSPORT_PRIVATE_KEY="..." PASSPORT_PUBLIC_KEY="..." ``` Il monitoraggio e il logging degli eventi di autenticazione aiutano a rilevare attacchi: ```php // app/Listeners/LogAuthenticationEvent.php namespace App\Listeners; use Illuminate\Auth\Events\Login; use Illuminate\Support\Facades\Log; class LogAuthenticationEvent { public function handle(Login $event): void { Log::info('Login utente', [ 'user_id' => $event->user->id, 'ip' => request()->ip(), 'user_agent' => request()->userAgent(), ]); } } ``` Gli [sviluppatori Laravel](/technologies/laravel) che implementano l'autenticazione API dovrebbero studiare approfonditamente la documentazione ufficiale di Sanctum e Passport. La scelta tra i due pacchetti dipende dai requisiti specifici dell'applicazione. ## Conclusione Laravel Sanctum e Passport rispondono a requisiti di autenticazione diversi. Sanctum offre una soluzione semplice ma sicura per SPA e app mobile con autenticazione token first-party. Passport implementa OAuth2 completo per scenari che richiedono autorizzazione di terze parti o comunicazione machine-to-machine. La scelta dovrebbe basarsi sui requisiti effettivi: Sanctum per la maggior parte delle applicazioni, Passport solo quando la funzionalità OAuth2 è indispensabile. Entrambi i pacchetti richiedono configurazione attenta delle scadenze dei token, degli scope e del rate limiting per implementazioni pronte per la produzione. Gli sviluppatori dovrebbero comprendere i meccanismi di protezione CSRF nell'autenticazione SPA, implementare la rotazione dei token e scrivere test completi per tutti i percorsi di autenticazione. Queste competenze sono rilevanti non solo per il lavoro quotidiano ma anche come componente importante dei colloqui tecnici per posizioni Laravel. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/it/blog/laravel/laravel-sanctum-vs-passport-api-authentication