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 vs Passport nel 2026: Autenticazione API e Domande da Colloquio

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.

CaratteristicaSanctumPassport
Caso d'uso principaleSPA, App Mobile, API SempliciOAuth2 Third-Party, Machine-to-Machine
Tipo di tokenToken hash sempliciJWT con scope OAuth2
Auth SessioneSì (basata su cookie)No
Grant OAuth2NessunoSpecifica completa
Dimensione pacchettoMinimaleSignificativa
ConfigurazioneSempliceComplessa

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.

config/sanctum.phpphp
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.

app/Http/Controllers/AuthController.phpphp
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.

routes/api.phpphp
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.

app/Models/User.phpphp
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:

app/Providers/AuthServiceProvider.phpphp
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.

app/Http/Controllers/OAuth/TokenController.phpphp
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:

app/Providers/AuthServiceProvider.phpphp
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:

routes/api.phpphp
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.

app/Http/Controllers/TokenController.phpphp
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:

config/sanctum.phpphp
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:

app/Console/Kernel.phpphp
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:

app/Providers/RouteServiceProvider.phpphp
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:

tests/Feature/ApiTest.phpphp
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:

config/auth.phpphp
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:

routes/api.phpphp
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.

.envphp
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:

app/Listeners/LogAuthenticationEvent.phpphp
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.

Sfida del giorno

Sapresti trovare il bug in Laravel?

Uno snippet reale, un bug nascosto, un tentativo al giorno. Senza account per provare.

Anthony Fillion-Maillet

Scritto da

Anthony Fillion-Maillet

Fondatore 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