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.
Condividi
Articoli correlati

Laravel Livewire 3 nel 2026: Applicazioni Reattive e Domande per Colloqui
Padroneggiare Laravel Livewire 3 con componenti reattivi, attributi PHP 8, integrazione Alpine.js e preparazione per colloqui tecnici.

Laravel Testing nel 2026: Pest, Mocking e Domande da Colloquio Tecnico
Una guida completa al testing Laravel con Pest 4: unit test, feature test, strategie di mocking, test architetturali e domande frequenti nei colloqui tecnici.

Laravel 12 nel 2026: Nuove Funzionalità, Starter Kit e Domande per Colloqui
Laravel 12 introduce Starter Kit completamente riprogettati con React 19, Vue 3, Livewire 4 e WorkOS AuthKit. Una guida completa alle nuove funzionalità, al percorso di aggiornamento e alle domande chiave per i colloqui tecnici del 2026.