Laravel API Authentication: Guida Completa a Passport e Sanctum

Intermedio
PHP Laravel

Impara a proteggere le tue API Laravel con le soluzioni di autenticazione ufficiali: Laravel Passport per OAuth2 e Laravel Sanctum per API token e SPA. Una guida approfondita per sviluppatori intermediate.

Pubblicato
Tag
laravel Sicurezza web API Autenticazione Sanctum passport oauth2 Sviluppo API

L'autenticazione è la pietra angolare di qualsiasi applicazione web moderna, e lo è ancora di più quando si tratta di API. Le API (Application Programming Interfaces) sono il motore invisibile che alimenta le nostre applicazioni, permettendo a diverse parti del sistema di comunicare tra loro, o a servizi esterni di interagire con la nostra logica di business. Proteggere queste interfacce è fondamentale per garantire che solo gli utenti e i servizi autorizzati possano accedervi e manipolarne i dati.

Laravel, uno dei framework PHP più popolari e apprezzati, offre strumenti robusti e flessibili per gestire l'autenticazione delle API. In questa guida completa, esploreremo in dettaglio le due soluzioni ufficiali fornite da Laravel: Laravel Passport per l'implementazione di un server OAuth2 completo e Laravel Sanctum per un'autenticazione API più leggera e mirata a Single Page Applications (SPA) e mobile apps. Capiremo quando e perché scegliere una soluzione rispetto all'altra, come configurarle e come utilizzarle efficacemente per costruire API sicure e scalabili.

Comprendere l'Autenticazione API in Laravel

Prima di addentrarci nelle specifiche di Passport e Sanctum, è cruciale comprendere le differenze fondamentali tra l'autenticazione per applicazioni web tradizionali e quella per API. Nelle applicazioni web basate su browser, l'autenticazione avviene tipicamente tramite sessioni e cookie. L'utente effettua il login, il server crea una sessione e imposta un cookie nel browser, che viene poi inviato automaticamente con ogni richiesta successiva per mantenere lo stato dell'utente. Questo approccio è "stateful" (basato sullo stato), poiché il server mantiene traccia dello stato di autenticazione di ciascun utente.

Le API, d'altra parte, sono spesso progettate per essere "stateless" (senza stato). Ciò significa che ogni richiesta API dovrebbe contenere tutte le informazioni necessarie per autenticare e autorizzare l'utente, senza fare affidamento su uno stato di sessione persistente lato server. Questa natura stateless rende le API più scalabili, più facili da distribuire su più server e più adatte a essere consumate da una varietà di client (applicazioni mobili, altre API, frontend JavaScript).

Per le API, l'autenticazione basata su token è il metodo più comune. In questo modello, un client (dopo aver fornito le credenziali) riceve un token di accesso. Questo token viene poi incluso in ogni richiesta successiva, tipicamente nell'header Authorization come Bearer Token. Il server valida il token per determinare l'identità e le autorizzazioni del client.

Laravel offre due pacchetti ufficiali per gestire questo tipo di autenticazione:

  • Laravel Passport: Un'implementazione completa di un server OAuth2. È la scelta ideale quando si ha bisogno di supportare l'autenticazione per applicazioni di terze parti o quando si desidera un controllo granulare sull'accesso ai dati attraverso un sistema di scopes e grants.
  • Laravel Sanctum: Una soluzione più leggera e semplificata per l'autenticazione basata su token API e per le applicazioni SPA (Single Page Applications). È perfetto per API di prima parte (quelle consumate dalla propria app frontend o mobile) o per l'autenticazione mobile/desktop con token a breve termine.

La scelta tra i due dipende dalle esigenze specifiche del tuo progetto. Esploriamoli in dettaglio.

Laravel Passport: La Soluzione OAuth2 Ufficiale

Laravel Passport è un pacchetto che fornisce un'implementazione completa e facile da usare di un server OAuth2 per la tua applicazione Laravel. OAuth2 (Open Authorization 2.0) è uno standard di settore per l'autorizzazione delegata, che consente a un'applicazione di accedere alle risorse di un utente su un altro servizio, senza mai vedere le credenziali dell'utente. È il protocollo utilizzato da giganti come Google, Facebook e Twitter per consentire ad applicazioni di terze parti di accedere ai dati degli utenti.

Perché usare OAuth2 con Passport?

Usare Passport ha senso quando:

  • Hai bisogno di autorizzare applicazioni di terze parti: Se vuoi che altri sviluppatori possano integrare le loro applicazioni con la tua API, Passport offre un modo sicuro e standardizzato per farlo.
  • Hai un'architettura a microservizi: Passport può centralizzare l'autenticazione e l'autorizzazione tra diversi servizi.
  • Richiedi un controllo granulare sulle autorizzazioni (scopes): OAuth2 permette di definire set specifici di permessi (scopes) che le applicazioni possono richiedere, dando agli utenti il controllo su quali dati condividere.
  • Vuoi aderire agli standard di settore: OAuth2 è ampiamente adottato e ben compreso, il che facilita l'integrazione e la sicurezza.

Installazione e Configurazione di Base di Passport

Per iniziare con Passport, devi installarlo tramite Composer:

composer require laravel/passport

Dopo l'installazione, devi eseguire le migrazioni del database per creare le tabelle necessarie a Passport (client OAuth, token di accesso, ecc.):

php artisan migrate

Successivamente, esegui il comando passport:install. Questo comando creerà le chiavi di crittografia necessarie per generare token sicuri e creerà anche client "personal access" e "password grant" per la tua applicazione. Questi client sono fondamentali per i metodi di autenticazione che vedremo a breve.

php artisan passport:install

Infine, nel tuo file app/Providers/AuthServiceProvider.php, devi chiamare il metodo Passport::routes() nel metodo boot() per registrare le rotte necessarie a Passport (ad esempio, per emettere token) e definire i tuoi scopes:

namespace App\\Providers;

use Illuminate\\Foundation\\Support\\Providers\\AuthServiceProvider as ServiceProvider;
use Illuminate\\Support\\Facades\\Gate;
use Laravel\\Passport\\Passport;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        // 'App\\Models\\Model' => 'App\\Policies\\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();

        Passport::tokensExpireIn(now()->addDays(15));
        Passport::refreshTokensExpireIn(now()->addDays(30));
        Passport::personalAccessTokensExpireIn(now()->addMonths(6));

        // Definizione degli scopes
        Passport::tokensCan([
            'view-users' => 'Visualizza informazioni utente',
            'manage-posts' => 'Gestisci i post del blog',
        ]);
    }
}

Assicurati anche che il tuo modello User utilizzi il trait HasApiTokens:

namespace App\\Models;

use Illuminate\\Contracts\\Auth\\MustVerifyEmail;
use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Foundation\\Auth\\User as Authenticatable;
use Illuminate\\Notifications\\Notifiable;
use Laravel\\Passport\\HasApiTokens; // Importa il trait

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    // ...
}

E nel file config/auth.php, imposta il driver API su passport:

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport', // Imposta il driver su 'passport'
            'provider' => 'users',
        ],
    ],

Tipi di Grant di Passport

Passport supporta diversi "grant types" di OAuth2, ognuno adatto a scenari specifici:

1. Personal Access Tokens (PAT)

I PAT sono token a lungo termine che un utente può generare per se stesso (ad esempio, tramite un'interfaccia utente nel suo profilo) per accedere all'API senza dover passare attraverso il flusso OAuth2 completo. Sono ideali per accedere alla propria API da uno script o da un'applicazione di prima parte che si fida pienamente dell'utente. Questi token non scadono per impostazione predefinita, ma puoi impostare una scadenza come mostrato nell'esempio AuthServiceProvider sopra.

Generazione di un PAT (lato server):

use Illuminate\\Http\\Request;

Route::post('/user/token', function (Request $request) {
    $request->validate([
        'name' => 'required',
        'abilities' => 'array',
    ]);

    $token = $request->user()->createToken($request->name, $request->abilities ?? []);

    return ['token' => $token->plainTextToken];
});

In questo esempio, un utente autenticato (tramite sessione web) può generare un token personale con un nome e, opzionalmente, degli abilities (scopes) specifici. Il plainTextToken è il valore che il client utilizzerà.

Utilizzo di un PAT (lato client):

Il client includerà il token nell'header Authorization:

GET /api/user
Authorization: Bearer <il_tuo_token_personale>
Accept: application/json

2. Password Grant Tokens

Questo grant type è pensato per le tue applicazioni di prima parte altamente affidabili (ad esempio, la tua applicazione mobile o desktop). Il client richiede un token di accesso inviando le credenziali dell'utente (email/username e password) direttamente all'API. Il server valida le credenziali e, se corrette, restituisce un token di accesso e un refresh token.

Per utilizzare il password grant, devi assicurarti che php artisan passport:install abbia creato un client di tipo Password Grant Client. Puoi verificarlo nella tabella oauth_clients del tuo database. Il client avrà un id e un secret che l'applicazione client dovrà conoscere.

Richiesta di un Password Grant Token (lato client, esempio con cURL):

curl -X POST "http://your-app.com/oauth/token" \\
    -H "Accept: application/json" \\
    -d "grant_type=password" \\
    -d "client_id=<ID_DEL_CLIENT_PASSWORD_GRANT>" \\
    -d "client_secret=<SECRET_DEL_CLIENT_PASSWORD_GRANT>" \\
    -d "username=user@example.com" \\
    -d "password=secret" \\
    -d "scope=*"

La risposta conterrà access_token, refresh_token, expires_in e token_type.

3. Authorization Code Grant

Questo è il grant type più sicuro e consigliato per le applicazioni di terze parti. Coinvolge un reindirizzamento dell'utente al server di autorizzazione (la tua applicazione Laravel) per concedere l'accesso. Il flusso è il seguente:

  1. L'applicazione di terze parti reindirizza l'utente al tuo server Laravel. La richiesta include un client_id, redirect_uri e scope.
  2. Laravel mostra all'utente una schermata di autorizzazione, chiedendo se desidera concedere l'accesso all'applicazione di terze parti.
  3. Se l'utente approva, Laravel reindirizza l'utente al redirect_uri dell'applicazione di terze parti, includendo un authorization_code.
  4. L'applicazione di terze parti utilizza questo authorization_code (insieme al suo client_id e client_secret) per richiedere un access_token al tuo server Laravel.
  5. Laravel verifica il codice e, se valido, restituisce l'access_token (e un refresh_token).

Questo grant type è più complesso da implementare sul lato client, ma offre la massima sicurezza poiché le credenziali dell'utente non vengono mai condivise con l'applicazione di terze parti.

4. Client Credentials Grant

Questo grant type è utilizzato quando l'applicazione client vuole accedere alle risorse protette dalla tua API per conto di se stessa, non per conto di un utente. È tipicamente usato per la comunicazione server-to-server o machine-to-machine, dove non c'è un utente finale coinvolto. Il client autentica se stesso direttamente con il suo client_id e client_secret per ottenere un token di accesso.

Richiesta di un Client Credentials Token (lato client, esempio con cURL):

curl -X POST "http://your-app.com/oauth/token" \\
    -H "Accept: application/json" \\
    -d "grant_type=client_credentials" \\
    -d "client_id=<ID_DEL_CLIENT_CREDENTIALS_GRANT>" \\
    -d "client_secret=<SECRET_DEL_CLIENT_CREDENTIALS_GRANT>" \\
    -d "scope=*"

Proteggere le Rotte con Passport

Una volta configurato Passport e ottenuto un token di accesso, puoi proteggere le tue rotte API utilizzando il middleware auth:api.

use Illuminate\\Http\\Request;
use Illuminate\\Support\\Facades\\Route;

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Route::middleware(['auth:api', 'scope:view-users'])->get('/users', function (Request $request) {
    // L'utente deve avere il permesso 'view-users'
    return App\\Models\\User::all();
});

Il middleware auth:api verificherà la presenza e la validità del token di accesso nell'header Authorization. Se il token è valido, l'utente sarà autenticato e disponibile tramite $request->user(). Puoi anche usare il middleware scope per controllare che il token abbia gli abilities (scopes) richiesti.

Laravel Sanctum: Autenticazione API Leggera e Semplice

Laravel Sanctum è una soluzione più snella rispetto a Passport, progettata per scenari specifici: autenticazione di Single Page Applications (SPA), applicazioni mobili e API semplici che richiedono token di accesso personali. A differenza di Passport che implementa l'intero standard OAuth2, Sanctum si concentra su un approccio più semplice e diretto.

Quando usare Sanctum?

Sanctum è la scelta migliore quando:

  • Stai costruendo un'API per la tua SPA: Sanctum offre un'autenticazione basata su sessione e cookie (con protezione CSRF) che funziona perfettamente con frontend JavaScript come Vue, React o Angular.
  • Stai creando un'API per la tua applicazione mobile: Puoi generare token API per gli utenti delle tue app iOS/Android.
  • Hai bisogno di token API personali: Similmente ai Personal Access Tokens di Passport, Sanctum permette agli utenti di generare token di accesso per interagire con l'API da script o applicazioni di terze parti di fiducia, ma in un pacchetto più leggero.
  • Non hai bisogno dell'intera complessità di OAuth2: Se non devi autorizzare applicazioni di terze parti complesse o implementare flussi di autorizzazione delegata, Sanctum è più che sufficiente.

Installazione e Configurazione di Base di Sanctum

Installa Sanctum tramite Composer:

composer require laravel/sanctum

Poi, pubblica il file di configurazione e le migrazioni:

php artisan vendor:publish --provider="Laravel\\Sanctum\\SanctumServiceProvider"
php artisan migrate

Questo creerà la tabella personal_access_tokens nel tuo database, necessaria per memorizzare i token API.

Assicurati che il tuo modello User utilizzi il trait HasApiTokens (lo stesso di Passport):

namespace App\\Models;

use Illuminate\\Contracts\\Auth\\MustVerifyEmail;
use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Foundation\\Auth\\User as Authenticatable;
use Illuminate\\Notifications\\Notifiable;
use Laravel\\Sanctum\\HasApiTokens; // Importa il trait (è lo stesso di Passport)

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    // ...
}

Nel file config/auth.php, imposta il driver API su sanctum:

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'sanctum', // Imposta il driver su 'sanctum'
            'provider' => 'users',
        ],
    ],

Infine, per le applicazioni SPA, devi aggiungere il middleware EnsureFrontendRequestsAreStateful al gruppo di middleware api nel tuo file app/Http/Kernel.php. Questo middleware è fondamentale per la gestione della sessione per le SPA.

    'api' => [
        \\Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \\Illuminate\\Routing\\Middleware\\SubstituteBindings::class,
    ],

Autenticazione per SPA (Single Page Applications)

Per le SPA, Sanctum offre un'esperienza di autenticazione senza attriti sfruttando i cookie di sessione di Laravel e la protezione CSRF. Il flusso è il seguente:

  1. Il tuo frontend (es. React su app.test) effettua una richiesta GET al tuo backend Laravel (es. api.test) all'endpoint /sanctum/csrf-cookie. Questa richiesta imposterà un cookie XSRF-TOKEN.
  2. Il frontend invia le credenziali dell'utente (email e password) a un endpoint di login della tua API (es. /api/login). Questa richiesta deve includere l'header X-XSRF-TOKEN con il valore del cookie ricevuto al passo 1.
  3. Laravel autentica l'utente e crea una sessione. Le richieste successive dal frontend includeranno automaticamente il cookie di sessione, mantenendo l'utente autenticato.

Configurazione SPA:

Nel tuo file config/sanctum.php, devi configurare stateful_domains per includere il dominio della tua SPA. Questo è cruciale affinché Sanctum sappia quali domini devono essere trattati come "stateful" (con sessione).

    'stateful_domains' => [
        'localhost', // Per sviluppo locale
        '127.0.0.1', // Per sviluppo locale
        'localhost:3000', // Esempio per React/Vue dev server
        'your-spa-domain.com', // Il dominio della tua SPA in produzione
    ],

Assicurati anche che la variabile d'ambiente SESSION_DOMAIN nel tuo .env sia configurata correttamente per consentire la condivisione dei cookie tra il tuo backend e il frontend (se su sottodomini diversi o domini correlati).

API Token (Bearer Token)

Per applicazioni mobili, applicazioni desktop o per consentire agli utenti di generare token per accedere alla tua API da script, Sanctum offre un meccanismo semplice per la creazione e la gestione di token API.

Generazione di un Token API (lato server):

Un utente può generare un token API tramite un'interfaccia web (dopo aver effettuato il login) o tramite un endpoint API dedicato dove fornisce le credenziali.

use Illuminate\\Http\\Request;
use Illuminate\\Support\\Facades\\Auth;
use Illuminate\\Validation\\ValidationException;

Route::post('/api/tokens', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
        'device_name' => 'required',
        'abilities' => 'array',
    ]);

    $user = Auth::attempt(['email' => $request->email, 'password' => $request->password]);

    if (! $user) {
        throw ValidationException::withMessages([
            'email' => ['Le credenziali fornite non sono corrette.'],
        ]);
    }

    $user = Auth::user(); // Ottieni l'utente autenticato
    $token = $user->createToken($request->device_name, $request->abilities ?? [])->plainTextToken;

    return response()->json(['token' => $token]);
});

In questo esempio, un utente invia email, password e un nome per il dispositivo. Se le credenziali sono valide, viene generato un token API con createToken(). Il plainTextToken è il valore che il client utilizzerà.

Utilizzo di un Token API (lato client):

Similmente a Passport, il client includerà il token nell'header Authorization:

GET /api/user
Authorization: Bearer <il_tuo_token_api>
Accept: application/json

Gestione delle Abilities (Scopes):

Sanctum consente di assegnare abilities (permessi) ai token. Puoi definire questi abilities quando crei il token e poi controllarli nelle tue rotte API.

// Generazione token con abilities
$token = $user->createToken('my-app-token', ['read', 'write-posts'])->plainTextToken;

// Protezione rotta con abilities
Route::middleware(['auth:sanctum', 'abilities:read'])->get('/posts', function (Request $request) {
    // Solo se il token ha l'ability 'read'
    return App\\Models\\Post::all();
});

Route::middleware(['auth:sanctum', 'abilities:write-posts'])->post('/posts', function (Request $request) {
    // Solo se il token ha l'ability 'write-posts'
    // ... crea post ...
});

Revoca dei Token:

È importante poter revocare i token quando non sono più necessari o in caso di compromissione. Puoi farlo facilmente:

// Revoca tutti i token per l'utente corrente
$request->user()->tokens()->delete();

// Revoca un token specifico per l'utente corrente
$request->user()->tokens()->where('id', $tokenId)->delete();

// Revoca il token corrente che ha fatto la richiesta
$request->user()->currentAccessToken()->delete();

Proteggere le Rotte con Sanctum

Per proteggere le tue rotte API con Sanctum, usa il middleware auth:sanctum.

use Illuminate\\Http\\Request;
use Illuminate\\Support\\Facades\\Route;

Route::middleware('auth:sanctum')->get('/api/user', function (Request $request) {
    return $request->user();
});

Questo middleware gestirà sia l'autenticazione basata su sessione (per SPA) sia l'autenticazione basata su token API (per mobile/altri client).

Scelta della Strategia di Autenticazione: Passport vs. Sanctum

La decisione su quale pacchetto utilizzare dipende dalle tue esigenze specifiche. Non esiste una soluzione migliore in assoluto, ma una più adatta al tuo caso d'uso.

Quando scegliere Laravel Passport:

  • Integrazione con terze parti: Se la tua API deve essere utilizzata da applicazioni di sviluppatori esterni che necessitano di un meccanismo standardizzato per ottenere l'autorizzazione dagli utenti (ad esempio, "Accedi con Google"), OAuth2 e Passport sono la scelta giusta.
  • Architetture complesse: Per microservizi o architetture distribuite dove un server di autorizzazione centralizzato è vantaggioso.
  • Controllo granulare e standard OAuth2: Se hai bisogno di tutte le funzionalità e la flessibilità dello standard OAuth2, inclusi i vari grant types e la gestione avanzata degli scopes.
  • Scalabilità e sicurezza di livello enterprise: OAuth2 è uno standard robusto e collaudato per scenari di grandi dimensioni.

Quando scegliere Laravel Sanctum:

  • Single Page Applications (SPA): Se stai costruendo un frontend JavaScript (React, Vue, Angular) che comunica con la tua API Laravel, Sanctum offre un'autenticazione senza soluzione di continuità basata su sessione e cookie, con protezione CSRF.
  • Applicazioni mobili o desktop di prima parte: Per le tue app native iOS/Android o desktop che devono autenticarsi con la tua API usando token API semplici.
  • API semplici con token personali: Se hai bisogno di un modo per gli utenti di generare token per script o integrazioni di fiducia, ma non hai bisogno della complessità di OAuth2.
  • Semplicità e leggerezza: Sanctum è più facile da configurare e mantenere rispetto a Passport, ideale per progetti in cui la complessità di OAuth2 è un'overkill.
  • API di prima parte: Quando l'API è destinata principalmente a essere consumata da applicazioni che controlli direttamente.

In sintesi, se la tua applicazione è un "provider" di API per un ecosistema più ampio o necessita di integrazioni complesse con terze parti, Passport è la via da seguire. Se stai costruendo un'applicazione monolitica con un frontend separato, un'app mobile o un'API per un uso interno, Sanctum è probabilmente la scelta più efficiente e rapida.

Esempi Pratici e Casi d'Uso

Vediamo alcuni scenari comuni e come Passport o Sanctum si applicano.

Scenario 1: API per un'Applicazione Mobile (Sanctum)

Supponiamo di avere un'applicazione mobile nativa che deve accedere a un'API Laravel. L'utente si registra o accede tramite l'app mobile.

Backend Laravel (Sanctum):

Endpoint di Login:

// routes/api.php
use Illuminate\\Http\\Request;
use Illuminate\\Support\\Facades\\Auth;
use Illuminate\\Validation\\ValidationException;

Route::post('/login', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
        'device_name' => 'required',
    ]);

    $user = Auth::attempt(['email' => $request->email, 'password' => $request->password]);

    if (! $user) {
        throw ValidationException::withMessages([
            'email' => ['Le credenziali fornite non sono corrette.'],
        ]);
    }

    $user = Auth::user();
    $token = $user->createToken($request->device_name)->plainTextToken;

    return response()->json(['token' => $token]);
});

// Endpoint protetto
Route::middleware('auth:sanctum')->get('/profile', function (Request $request) {
    return $request->user();
});

Flusso lato Mobile App (concettuale):

  1. L'utente inserisce email e password nell'app.
  2. L'app invia una richiesta POST a /api/login con email, password e un device_name (es. "iPhone di Mario").
  3. L'API Laravel risponde con un token.
  4. L'app salva il token in modo sicuro (es. Keychain su iOS, SharedPreferences su Android).
  5. Per le richieste successive, l'app include il token nell'header Authorization: Bearer <token>.
  6. Quando l'utente si disconnette, l'app invia una richiesta all'API per revocare il token corrente.
// Endpoint per il logout (revoca del token)
Route::middleware('auth:sanctum')->post('/logout', function (Request $request) {
    $request->user()->currentAccessToken()->delete();
    return response()->json(['message' => 'Token revocato con successo.']);
});

Scenario 2: API per un'Applicazione di Terze Parti (Passport - Authorization Code Grant)

Immagina di aver creato una piattaforma e di voler consentire a sviluppatori esterni di creare applicazioni che interagiscono con i dati degli utenti (es. pubblicare post sul loro blog sulla tua piattaforma).

Backend Laravel (Passport):

  • Assicurati di aver configurato Passport e di aver registrato un client di tipo Authorization Code Grant (questo di solito avviene tramite php artisan passport:client --name="Terza Parte App" --redirect_uri=http://third-party.com/callback).
  • Le rotte API saranno protette con auth:api e, se necessario, con scope.

Flusso lato Applicazione di Terze Parti (concettuale):

  1. L'applicazione di terze parti mostra un pulsante "Connetti con la mia Piattaforma".
  2. Quando l'utente clicca, viene reindirizzato all'URL di autorizzazione di Laravel (es. http://your-platform.com/oauth/authorize?client_id=...&redirect_uri=...&response_type=code&scope=...).
  3. L'utente accede alla tua piattaforma (se non già autenticato) e vede una schermata di autorizzazione che chiede se vuole concedere i permessi richiesti all'app di terze parti.
  4. Se l'utente approva, Laravel reindirizza l'utente al redirect_uri dell'app di terze parti con un code.
  5. L'app di terze parti, sul suo backend, scambia questo code con un access_token e un refresh_token inviando una richiesta POST a http://your-platform.com/oauth/token con il code, client_id, client_secret e redirect_uri.
  6. L'app di terze parti salva il token di accesso e lo usa per chiamare le API protette di Laravel per conto dell'utente, includendolo nell'header Authorization.

Scenario 3: API Interna tra Servizi (Passport - Client Credentials Grant o Sanctum PAT)

Se hai due microservizi Laravel (es. un servizio Users e un servizio Orders) che devono comunicare tra loro senza l'intervento di un utente finale.

Backend Laravel (Servizio Users - Passport Client Credentials):

  • Crea un client di tipo Client Credentials Grant per il servizio Orders (es. php artisan passport:client --name="Orders Service" --client).
  • Il servizio Orders userà il client_id e client_secret per ottenere un token.

Backend Laravel (Servizio Orders - Concettuale):

  1. Il servizio Orders invia una richiesta POST a http://users-service.com/oauth/token con grant_type=client_credentials, client_id, client_secret e scope=*.
  2. Riceve un access_token.
  3. Per chiamare le API del servizio Users (es. /api/users/{id}), include l'access_token nell'header Authorization.

Alternativamente, potresti usare i Personal Access Tokens di Sanctum se la comunicazione è tra servizi che "appartengono" alla stessa entità logica e non richiedono la complessità di OAuth2. Un utente amministratore potrebbe generare un PAT con le abilities necessarie e il servizio Orders lo userebbe direttamente.

Errori Comuni e Best Practices

Errori Comuni

  1. Mancata Configurazione del Middleware: Dimenticare di applicare auth:api (Passport) o auth:sanctum (Sanctum) alle rotte protette, o configurare erroneamente il driver nel config/auth.php.
  2. Header Authorization Non Corretto: Non includere il prefisso Bearer prima del token, o inviare il token in un header sbagliato.
    • Corretto: Authorization: Bearer <token>
    • Sbagliato: Authorization: <token>, X-API-Token: <token> (a meno che non sia una convenzione personalizzata).
  3. Problemi CORS (Cross-Origin Resource Sharing): Se il tuo frontend JavaScript è su un dominio diverso dalla tua API, potresti incontrare errori CORS. Laravel include un middleware CORS (Fruitcake\\Cors\\HandleCors) che deve essere configurato correttamente in config/cors.php per consentire le richieste dal tuo dominio frontend.
  4. Token Scaduti/Invalidi Non Gestiti: Il client non gestisce correttamente le risposte 401 (Unauthorized) quando un token è scaduto o non valido, portando a un'esperienza utente scadente o a richieste fallite.
  5. Mancanza di Revoca dei Token: Non implementare un meccanismo per la revoca dei token, specialmente per i token personali o in caso di compromissioni.
  6. SESSION_DOMAIN e SANCTUM_STATEFUL_DOMAINS non configurati (per Sanctum SPA): Questi sono cruciali per il corretto funzionamento dell'autenticazione basata su sessione di Sanctum in ambienti multi-dominio.

Best Practices

  1. Usare HTTPS Sempre: Tutte le comunicazioni API devono avvenire su HTTPS per prevenire l'intercettazione dei token e delle credenziali.
  2. Scadenza dei Token: Imposta una scadenza ragionevole per i token di accesso. Per Passport, usa Passport::tokensExpireIn() e Passport::refreshTokensExpireIn(). Per Sanctum, i token personali non scadono di default, quindi considera di implementare una logica di scadenza personalizzata o di revocare i token dopo un certo periodo di inattività.
  3. Revoca dei Token: Offri sempre agli utenti la possibilità di revocare i propri token. Questo è fondamentale per la sicurezza se un dispositivo viene perso o compromesso.
  4. Logging degli Accessi: Registra gli accessi API e i tentativi falliti. Questo può aiutare a rilevare attività sospette.
  5. Validazione degli Input: Valida sempre tutti gli input delle richieste API per prevenire vulnerabilità come SQL injection o XSS.
  6. Limiting Token Abilities (Scopes): Concedi ai token solo le autorizzazioni minime necessarie (Principio del minimo privilegio). Evita di usare scope=* in produzione a meno che non sia strettamente necessario.
  7. Rate Limiting: Implementa il rate limiting sulle tue API per prevenire attacchi di forza bruta e abusi. Laravel offre un middleware throttle per questo scopo.
  8. Protezione CSRF per SPA (Sanctum): Assicurati che il tuo frontend SPA faccia sempre prima una richiesta a /sanctum/csrf-cookie e invii il token CSRF (X-XSRF-TOKEN) nelle richieste POST, PUT, PATCH, DELETE.
  9. Archiviazione Sicura dei Token: Lato client (app mobile, browser), i token dovrebbero essere archiviati in modo sicuro (es. localStorage con cautela e solo per token a breve termine, IndexedDB, HttpOnly cookies per SPA, Keychain per iOS, SharedPreferences con crittografia per Android).

Prossimi Passi e Risorse per Approfondire

L'autenticazione API è un campo vasto e in continua evoluzione. Ecco alcuni passi per continuare ad approfondire:

  • Documentazione Ufficiale Laravel: La documentazione di Laravel per Passport e Sanctum è eccellente e costantemente aggiornata. È la tua risorsa primaria per dettagli specifici e nuove funzionalità.
  • Approfondire OAuth2: Se hai scelto Passport, dedicare tempo a comprendere a fondo lo standard OAuth2 (RFC 6749) ti darà una base solida per affrontare scenari complessi e implementazioni personalizzate.
  • Test delle API: Utilizza strumenti come Postman, Insomnia o cURL per testare le tue API e i flussi di autenticazione. Questo ti aiuterà a capire come i token vengono inviati e ricevuti.
  • Gestione degli Scopes: Esplora in dettaglio come definire e applicare gli abilities (Sanctum) o scopes (Passport) per un controllo ancora più granulare sulle autorizzazioni.
  • Integrazione con Identity Providers (IdP): Considera l'integrazione con servizi di gestione delle identità di terze parti come Okta, Auth0, Google Identity Platform, se la tua applicazione ha esigenze avanzate di single sign-on (SSO) o federazione delle identità.
  • Sicurezza delle API: Oltre all'autenticazione, studia altre pratiche di sicurezza per le API, come la protezione contro attacchi DDoS, la gestione delle vulnerabilità OWASP API Security Top 10 e l'implementazione di Content Security Policy (CSP).

Proteggere le tue API Laravel con Passport o Sanctum è un passo fondamentale per costruire applicazioni robuste e affidabili. Comprendendo le differenze e i punti di forza di ciascuna soluzione, sarai in grado di fare la scelta giusta per il tuo progetto e implementare una strategia di autenticazione efficace e sicura.