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.

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.
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.
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.
// 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.
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.
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.
composer require laravel/passport
php artisan passport:installIl comando passport:install genera le chiavi di crittografia e crea i client Personal Access e Password Grant.
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:
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.
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.
// 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:
// 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:
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:
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']);
});Pronto a superare i tuoi colloqui su Laravel?
Pratica con i nostri simulatori interattivi, flashcards e test tecnici.
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.
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:
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:
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:
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:
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:
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:
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.
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:
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 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.
Passez à la pratique !
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.
Sapresti trovare il bug in Laravel?
Uno snippet reale, un bug nascosto, un tentativo al giorno. Senza account per provare.

Scritto da
Anthony Fillion-MailletFondatore di SharpSkill
Sviluppatore fullstack da oltre 10 anni. Guida SharpSkill e risponde di tutto ciò che vi viene pubblicato.
Aggiornato il 26 luglio 2026
Condividi
Articoli correlati

Domande Colloquio PHP Laravel Framework 2026: Eloquent, Code e Pattern Architetturali
Preparazione ai colloqui Laravel 2026: Eloquent ORM, sistemi di code, Service Container e pattern architetturali moderni con esempi di codice pratici.

Laravel Octane nel 2026: Swoole, RoadRunner e Ottimizzazione delle Performance
Guida completa a Laravel Octane 2.19 con FrankenPHP, Swoole e RoadRunner. Selezione del server, prevenzione memory leak, task concorrenti e strategie di deployment in produzione per applicazioni PHP ad alte prestazioni.

Domande per Colloqui PHP Laravel Developer 2026: Guida Completa alla Preparazione
Guida completa alle domande per colloqui PHP Laravel 2026 con Eloquent ORM, Service Container, autenticazione, code e testing.