Prologo
Primi Passi
Architettura
Le Basi
- Routing
- Middleware
- Protezione da CSRF
- Controller
- Richieste
- Risposte
- Views
- Blade
- Vite
- URL
- Sessioni
- Validazione
- Errori
- Logging
Approfondimenti
- Artisan
- Broadcasting
- Cache
- Collezioni
- Concorrenza
- Contesto
- Contratti
- Eventi
- File System
- Helpers
- Client HTTP
- Localizzazione
- Notifiche
- Sviluppo di Package
- Processi
- Code
- Rate-limiting
- Stringhe
- Scheduling di Task
Sicurezza
Database
Eloquent ORM
Testing
Package
Autenticazione
- Introduzione
- Guida Rapida all’Autenticazione
- Autenticare manualmente gli utenti
- Autenticazione HTTP di Base
- Disconnessione
- Conferma Password
- Aggiungere Guard Personalizzate
- Aggiungere Provider Utente Personalizzati
- Rielaborazione Automatica della Password
- Eventi
Introduzione
Molte applicazioni web offrono un modo per gli utenti di autenticarsi e "accedere" all’applicazione. Implementare questa funzionalità nelle applicazioni web può essere un compito complesso e potenzialmente rischioso. Per questo motivo, Laravel si impegna a fornirti gli strumenti necessari per implementare l’autenticazione in modo rapido, sicuro e semplice.
Alla base, le funzionalità di autenticazione di Laravel sono costituite da "guards" e "providers". I guards definiscono come gli utenti vengono autenticati per ogni richiesta. Ad esempio, Laravel include un session
guard che mantiene lo stato utilizzando la memorizzazione delle sessioni e i cookie.
I providers definiscono come gli utenti vengono recuperati dal tuo storage persistente. Laravel supporta il recupero degli utenti utilizzando Eloquent e il query builder del database. Tuttavia, sei libero di definire provider aggiuntivi secondo le necessità della tua applicazione.
Il file di configurazione per l’autenticazione della tua applicazione si trova in config/auth.php
. Questo file contiene diverse opzioni ben documentate per modificare il comportamento dei servizi di autenticazione di Laravel.
I guards e i providers non devono essere confusi con "ruoli" e "permessi". Per saperne di più sull’autorizzazione delle azioni degli utenti tramite i permessi, consulta la documentazione sull’autorizzazione.
Starter Kits
Vuoi iniziare rapidamente? Installa un Laravel application starter kit in una nuova applicazione Laravel. Dopo aver migrato il database, apri il browser su /register
o su qualsiasi altro URL assegnato alla tua applicazione. Gli starter kits si occuperanno di strutturare tutto il sistema di autenticazione!
Anche se decidi di non usare uno starter kit nella tua applicazione Laravel finale, installare il Laravel Breeze starter kit può essere un’ottima occasione per imparare come implementare tutte le funzionalità di autenticazione di Laravel in un progetto reale. Poiché Laravel Breeze crea controller di autenticazione, rotte e viste per te, puoi esaminare il codice in questi file per capire come implementare le funzionalità di autenticazione di Laravel.
Considerazioni sul Database
Per impostazione predefinita, Laravel include un modello App\Models\User
Eloquent model nella directory app/Models
. Questo modello può essere usato con il driver di autenticazione Eloquent predefinito.
Se la tua applicazione non usa Eloquent, puoi utilizzare il provider di autenticazione database
che sfrutta il query builder di Laravel. Se la tua applicazione utilizza MongoDB, consulta la documentazione ufficiale sull’autenticazione utenti di Laravel per MongoDB.
Quando crei lo schema del database per il modello App\Models\User
, assicurati che la colonna della password abbia almeno 60 caratteri. Naturalmente, la migrazione della tabella users
inclusa nelle nuove applicazioni Laravel crea già una colonna che supera questa lunghezza.
Inoltre, verifica che la tua tabella users
(o equivalente) contenga una colonna remember_token
di tipo stringa, nullable e di 100 caratteri. Questa colonna verrà usata per memorizzare un token per gli utenti che selezionano l’opzione "ricordami" durante l’accesso alla tua applicazione. Anche in questo caso, la migrazione predefinita della tabella users
inclusa nelle nuove applicazioni Laravel contiene già questa colonna.
Panoramica dell’Ecosistema
Laravel offre diversi pacchetti relativi all’autenticazione. Prima di procedere, esamineremo l’ecosistema generale dell’autenticazione in Laravel e discuteremo lo scopo di ciascun pacchetto.
Innanzitutto, considera come funziona l’autenticazione. Quando si utilizza un browser web, un utente fornisce il proprio username e password tramite un modulo di login. Se queste credenziali sono corrette, l’applicazione memorizza le informazioni sull’utente autenticato nella session dell’utente. Un cookie inviato al browser contiene l’ID della sessione in modo che le richieste successive all’applicazione possano associare l’utente alla sessione corretta. Dopo che il cookie della sessione viene ricevuto, l’applicazione recupera i dati della sessione basandosi sull’ID della sessione, rileva che le informazioni di autenticazione sono state memorizzate nella sessione e considera l’utente come "autenticato".
Quando un servizio remoto deve autenticarsi per accedere a un’API, solitamente non si usano i cookie per l’autenticazione perché non c’è un browser web. Invece, il servizio remoto invia un token API all’API ad ogni richiesta. L’applicazione può validare il token in arrivo confrontandolo con una tabella di token API validi e "autenticare" la richiesta come eseguita dall’utente associato a quel token API.
Servizi di Autenticazione del Browser Integrati in Laravel
Laravel include servizi di autenticazione e sessione integrati, solitamente accessibili tramite le facade Auth
e Session
. Queste funzionalità offrono l’autenticazione basata su cookie per le richieste avviate dai browser web. Forniscono metodi che ti permettono di verificare le credenziali di un utente e di autenticare l’utente. Inoltre, questi servizi memorizzano automaticamente i dati di autenticazione corretti nella sessione dell’utente e emettono il cookie di sessione dell’utente. Una discussione su come utilizzare questi servizi è contenuta in questa documentazione.
Starter Kit per Applicazioni
Come descritto in questa documentazione, puoi interagire manualmente con questi servizi di autenticazione per costruire il livello di autenticazione della tua applicazione. Tuttavia, per aiutarti a iniziare più rapidamente, abbiamo rilasciato pacchetti gratuiti che forniscono una solida struttura moderna per l’intero strato di autenticazione. Questi pacchetti sono Laravel Breeze, Laravel Jetstream e Laravel Fortify.
Laravel Breeze è un’implementazione semplice e minimale di tutte le funzionalità di autenticazione di Laravel, inclusi login, registrazione, reset della password, verifica dell’email e conferma della password. Il layer di vista di Laravel Breeze è composto da semplici template Blade stilizzati con Tailwind CSS. Per iniziare, consulta la documentazione sugli starter kits per applicazioni di Laravel.
Laravel Fortify è un backend di autenticazione headless per Laravel che implementa molte delle funzionalità presentate in questa documentazione, inclusa l’autenticazione basata su cookie e altre funzionalità come l’autenticazione a due fattori e la verifica dell’email. Fortify fornisce il backend di autenticazione per Laravel Jetstream o può essere utilizzato indipendentemente in combinazione con Laravel Sanctum per fornire l’autenticazione per una SPA che necessita di autenticarsi con Laravel.
Laravel Jetstream è uno starter kit per applicazioni robusto che utilizza e espone i servizi di autenticazione di Laravel Fortify con un’interfaccia utente bella e moderna alimentata da Tailwind CSS, Livewire e/o Inertia. Laravel Jetstream include supporto opzionale per l’autenticazione a due fattori, il supporto ai team, la gestione delle sessioni del browser, la gestione del profilo e l’integrazione integrata con Laravel Sanctum per offrire l’autenticazione tramite token API. Le offerte di autenticazione API di Laravel sono descritte di seguito.
I Servizi di Autenticazione API di Laravel
Laravel offre due pacchetti opzionali per aiutarti a gestire i token API e autenticare le richieste effettuate con questi token: Passport e Sanctum. Tieni presente che queste librerie e le librerie di autenticazione basate su cookie integrate in Laravel non sono mutualmente esclusive. Queste librerie si concentrano principalmente sull’autenticazione tramite token API, mentre i servizi di autenticazione integrati si focalizzano sull’autenticazione tramite cookie nel browser. Molte applicazioni utilizzeranno sia i servizi di autenticazione basati su cookie di Laravel che uno dei pacchetti di autenticazione API di Laravel.
Passport
Passport è un provider di autenticazione OAuth2, che offre una varietà di "grant types" OAuth2 che permettono di emettere diversi tipi di token. In generale, questo è un pacchetto robusto e complesso per l’autenticazione API. Tuttavia, la maggior parte delle applicazioni non richiede le funzionalità complesse previste dalla specifica OAuth2, che possono risultare confuse sia per gli utenti che per gli sviluppatori. Inoltre, storicamente gli sviluppatori hanno avuto difficoltà ad autenticare applicazioni SPA o applicazioni mobili utilizzando provider di autenticazione OAuth2 come Passport.
Sanctum
In risposta alla complessità di OAuth2 e alla confusione degli sviluppatori, abbiamo deciso di creare un pacchetto di autenticazione più semplice e snello che potesse gestire sia le richieste web di prima parte da un browser che le richieste API tramite token. Questo obiettivo è stato raggiunto con il rilascio di Laravel Sanctum, che dovrebbe essere considerato il pacchetto di autenticazione preferito e raccomandato per le applicazioni che offriranno un’interfaccia web di prima parte oltre a un’API, o che saranno supportate da un’applicazione single-page (SPA) separata dall’applicazione backend Laravel, o per applicazioni che offrono un client mobile.
Laravel Sanctum è un pacchetto di autenticazione ibrido web/API che può gestire l’intero processo di autenticazione della tua applicazione. Ciò è possibile perché, quando un’applicazione basata su Sanctum riceve una richiesta, Sanctum determinerà innanzitutto se la richiesta include un cookie di sessione che fa riferimento a una sessione autenticata. Sanctum realizza ciò chiamando i servizi di autenticazione integrati di Laravel di cui abbiamo parlato in precedenza. Se la richiesta non viene autenticata tramite un cookie di sessione, Sanctum controllerà la presenza di un token API nella richiesta. Se è presente un token API, Sanctum autenticherà la richiesta utilizzando quel token. Per saperne di più su questo processo, consulta la documentazione di Sanctum su "come funziona".
Laravel Sanctum è il pacchetto API che abbiamo scelto di includere nel starter kit di applicazione Laravel Jetstream perché riteniamo sia la soluzione migliore per la maggior parte delle esigenze di autenticazione delle applicazioni web.
Riepilogo e Scelta dello Stack
In sintesi, se la tua applicazione sarà accessibile tramite un browser e stai costruendo un’applicazione Laravel monolitica, utilizzerai i servizi di autenticazione integrati di Laravel.
Successivamente, se la tua applicazione offre un’API che sarà consumata da terzi, dovrai scegliere tra Passport o Sanctum per fornire l’autenticazione tramite token API. In generale, Sanctum dovrebbe essere preferito quando possibile, poiché è una soluzione semplice e completa per l’autenticazione API, l’autenticazione delle SPA e l’autenticazione mobile, inclusa la gestione di "scopes" o "abilities".
Se stai costruendo una single-page application (SPA) alimentata da un backend Laravel, dovresti usare Laravel Sanctum. Quando usi Sanctum, dovrai implementare manualmente le tue rotte di autenticazione backend oppure utilizzare Laravel Fortify come servizio di autenticazione headless che fornisce rotte e controller per funzionalità come la registrazione, il reset della password, la verifica dell’email e altro.
Passport può essere scelto quando la tua applicazione ha assolutamente bisogno di tutte le funzionalità fornite dalla specifica OAuth2.
E, se desideri iniziare rapidamente, siamo lieti di raccomandare Laravel Breeze come modo veloce per avviare una nuova applicazione Laravel che utilizza già il nostro stack di autenticazione preferito, ovvero i servizi di autenticazione integrati di Laravel e Laravel Sanctum.
Guida Rapida all’Autenticazione
Questa parte della documentazione tratta l’autenticazione degli utenti tramite i starter kit per applicazioni Laravel, che include lo scaffolding dell’interfaccia utente per aiutarti a iniziare rapidamente. Se desideri integrare direttamente i sistemi di autenticazione di Laravel, consulta la documentazione su autenticare manualmente gli utenti.
Installa uno Starter Kit
Per prima cosa, dovresti installare uno starter kit per applicazioni Laravel. I nostri starter kit attuali, Laravel Breeze e Laravel Jetstream, offrono punti di partenza ben progettati per integrare l’autenticazione nella tua nuova applicazione Laravel.
Laravel Breeze è un’implementazione minimale e semplice di tutte le funzionalità di autenticazione di Laravel, inclusi login, registrazione, reset della password, verifica dell’email e conferma della password. Il layer di visualizzazione di Laravel Breeze è composto da semplici Blade templates stilizzati con Tailwind CSS. Inoltre, Breeze offre opzioni di scaffolding basate su Livewire o Inertia, con la possibilità di utilizzare Vue o React per lo scaffolding basato su Inertia.
Laravel Jetstream è uno starter kit per applicazioni più robusto che include il supporto per lo scaffolding della tua applicazione con Livewire o Inertia e Vue. Inoltre, Jetstream offre supporto opzionale per l’autenticazione a due fattori, team, gestione del profilo, gestione delle sessioni del browser, supporto API tramite Laravel Sanctum, cancellazione dell’account e altro.
Recuperare l’Utente Autenticato
Dopo aver installato uno starter kit di autenticazione e permesso agli utenti di registrarsi e autenticarsi con la tua applicazione, spesso avrai bisogno di interagire con l’utente attualmente autenticato. Durante la gestione di una richiesta in arrivo, puoi accedere all’utente autenticato tramite il metodo user
della facade Auth
:
use Illuminate\Support\Facades\Auth;
// Recupera l'utente attualmente autenticato...
$user = Auth::user();
// Recupera l'ID dell'utente attualmente autenticato...
$id = Auth::id();
In alternativa, una volta che un utente è autenticato, puoi accedere all’utente autenticato tramite un’istanza di Illuminate\Http\Request
. Ricorda, le classi con type-hint vengono automaticamente iniettate nei metodi del tuo controller. Tipizzando l’oggetto Illuminate\Http\Request
, puoi accedere facilmente all’utente autenticato da qualsiasi metodo del controller nella tua applicazione tramite il metodo user
della richiesta:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class FlightController extends Controller
{
/**
* Aggiorna le informazioni del volo per un volo esistente.
*/
public function update(Request $request): RedirectResponse
{
$user = $request->user();
// ...
return redirect('/flights');
}
}
Determinare se l’utente corrente è autenticato
Per determinare se l’utente che effettua la richiesta HTTP in entrata è autenticato, puoi utilizzare il metodo check
sul facade Auth
. Questo metodo restituirà true
se l’utente è autenticato:
use Illuminate\Support\Facades\Auth;
if (Auth::check()) {
// L'utente è connesso...
}
Anche se è possibile determinare se un utente è autenticato utilizzando il metodo
check
, di solito utilizzerai un middleware per verificare che l’utente sia autenticato prima di consentirgli l’accesso a determinate rotte / controller. Per saperne di più, consulta la documentazione su proteggere le rotte.
Proteggere le Rotte
I middleware delle rotte possono essere usati per permettere l’accesso a una rotta solo agli utenti autenticati. Laravel include un middleware auth
, che è un alias del middleware per la classe Illuminate\Auth\Middleware\Authenticate
. Poiché questo middleware è già aliasato internamente da Laravel, tutto ciò che devi fare è associare il middleware alla definizione della rotta:
Route::get('/flights', function () {
// Solo gli utenti autenticati possono accedere a questa rotta...
})->middleware('auth');
Reindirizzare gli Utenti Non Autenticati
Quando il middleware auth
rileva un utente non autenticato, reindirizzerà l’utente alla login
route nominata. Puoi modificare questo comportamento usando il metodo redirectGuestsTo
nel file bootstrap/app.php
della tua applicazione:
use Illuminate\Http\Request;
->withMiddleware(function (Middleware $middleware) {
$middleware->redirectGuestsTo('/login');
// Using a closure...
$middleware->redirectGuestsTo(fn (Request $request) => route('login'));
})
Specificare una Guard
Quando si applica il middleware auth
a una rotta, è possibile specificare anche quale "guard" utilizzare per autenticare l’utente. La guard specificata deve corrispondere a una delle chiavi nell’array guards
del tuo file di configurazione auth.php
:
Route::get('/flights', function () {
// Only authenticated users may access this route...
})->middleware('auth:admin');
Login Throttling
Se stai usando i starter kits Laravel Breeze o Laravel Jetstream, il rate limiting verrà applicato automaticamente ai tentativi di accesso. Per impostazione predefinita, l’utente non potrà accedere per un minuto se non fornisce le credenziali corrette dopo diversi tentativi. Il throttling è unico per il nome utente / indirizzo email dell’utente e il loro indirizzo IP.
Se desideri applicare il rate limiting ad altre rotte nella tua applicazione, consulta la documentazione sul rate limiting.
Autenticare manualmente gli utenti
Non è necessario utilizzare il sistema di autenticazione incluso nei starter kit per applicazioni di Laravel. Se decidi di non usare questo sistema, dovrai gestire l’autenticazione degli utenti direttamente con le classi di autenticazione di Laravel. Non preoccuparti, è molto semplice!
Accediamo ai servizi di autenticazione di Laravel tramite la facade Auth
, quindi dobbiamo assicurarci di importare la facade Auth
all’inizio della classe. Successivamente, esaminiamo il metodo attempt
. Il metodo attempt
viene solitamente utilizzato per gestire i tentativi di autenticazione dal modulo di "login" della tua applicazione. Se l’autenticazione ha successo, dovresti rigenerare la sessione dell’utente per prevenire la session fixation:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
/**
* Gestisce un tentativo di autenticazione.
*/
public function authenticate(Request $request): RedirectResponse
{
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->intended('dashboard');
}
return back()->withErrors([
'email' => 'Le credenziali fornite non corrispondono ai nostri record.',
])->onlyInput('email');
}
}
Il metodo attempt
accetta un array di coppie chiave/valore come primo argomento. I valori nell’array verranno utilizzati per trovare l’utente nella tua tabella del database. Quindi, nell’esempio sopra, l’utente verrà recuperato in base al valore della colonna email
. Se l’utente viene trovato, la password criptata memorizzata nel database sarà confrontata con il valore password
passato al metodo tramite l’array. Non dovresti criptare il valore password
della richiesta in arrivo, poiché il framework cripta automaticamente il valore prima di confrontarlo con la password criptata nel database. Una sessione autenticata verrà avviata per l’utente se le due password criptate corrispondono.
Ricorda, i servizi di autenticazione di Laravel recuperano gli utenti dal tuo database in base alla configurazione del "provider" della tua guard di autenticazione. Nel file di configurazione predefinito config/auth.php
, è specificato il provider di utenti Eloquent ed è indicato di utilizzare il modello App\Models\User
per recuperare gli utenti. Puoi modificare questi valori nel tuo file di configurazione in base alle esigenze della tua applicazione.
Il metodo attempt
restituirà true
se l’autenticazione ha avuto successo. Altrimenti, verrà restituito false
.
Il metodo intended
fornito dal redirector di Laravel reindirizzerà l’utente all’URL che stava tentando di accedere prima di essere intercettato dal middleware di autenticazione. È possibile fornire un URI di riserva a questo metodo nel caso in cui la destinazione prevista non sia disponibile.
Specificare Condizioni Aggiuntive
Se desideri, puoi aggiungere condizioni extra alla query di autenticazione oltre all’email e alla password dell’utente. Per fare ciò, basta aggiungere le condizioni di query all’array passato al metodo attempt
. Ad esempio, possiamo verificare che l’utente sia contrassegnato come "attivo":
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// Authentication was successful...
}
Per condizioni di query complesse, puoi fornire una closure nel tuo array di credenziali. Questa closure verrà invocata con l’istanza della query, permettendoti di personalizzare la query in base alle esigenze della tua applicazione:
use Illuminate\Database\Eloquent\Builder;
if (Auth::attempt([
'email' => $email,
'password' => $password,
fn (Builder $query) => $query->has('activeSubscription'),
])) {
// Authentication was successful...
}
In questi esempi,
Il metodo attemptWhen
, che riceve una closure come secondo argomento, può essere usato per eseguire un’ispezione più approfondita dell’utente potenziale prima di autenticarlo effettivamente. La closure riceve l’utente potenziale e deve restituire true
o false
per indicare se l’utente può essere autenticato:
if (Auth::attemptWhen([
'email' => $email,
'password' => $password,
], function (User $user) {
return $user->isNotBanned();
})) {
// Authentication was successful...
}
Accesso a istanze specifiche di Guard
Tramite il metodo guard
della facade Auth
, puoi specificare quale istanza di guard desideri utilizzare per autenticare l’utente. Questo ti permette di gestire l’autenticazione per parti separate della tua applicazione utilizzando modelli autenticabili o tabelle utenti completamente separate.
Il nome del guard passato al metodo guard
deve corrispondere a uno dei guard configurati nel file di configurazione auth.php
:
if (Auth::guard('admin')->attempt($credentials)) {
// ...
}
Ricordare gli Utenti
Molte applicazioni web offrono una casella di controllo "ricordami" nel modulo di accesso. Se desideri fornire la funzionalità "ricordami" nella tua applicazione, puoi passare un valore booleano come secondo argomento al metodo attempt
.
Quando questo valore è true
, Laravel manterrà l’utente autenticato indefinitamente o fino a quando non effettua manualmente il logout. La tua tabella users
deve includere la colonna di tipo stringa remember_token
, che verrà utilizzata per memorizzare il token "ricordami". La migrazione della tabella users
inclusa nelle nuove applicazioni Laravel include già questa colonna:
use Illuminate\Support\Facades\Auth;
if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
// L'utente viene ricordato...
}
Se la tua applicazione offre la funzionalità "ricordami", puoi usare il metodo viaRemember
per determinare se l’utente attualmente autenticato è stato autenticato tramite il cookie "ricordami":
use Illuminate\Support\Facades\Auth;
if (Auth::viaRemember()) {
// ...
}
Altri Metodi di Autenticazione
Autenticare un’Istanza di Utente
Se hai bisogno di impostare un’istanza utente esistente come utente autenticato corrente, puoi passare l’istanza utente al metodo login
della facciata Auth
. L’istanza utente fornita deve essere un’implementazione del contratto Illuminate\Contracts\Auth\Authenticatable
contratto. Il modello App\Models\User
incluso in Laravel implementa già questa interfaccia. Questo metodo di autenticazione è utile quando hai già un’istanza utente valida, ad esempio subito dopo che un utente si registra nella tua applicazione:
use Illuminate\Support\Facades\Auth;
Auth::login($user);
Puoi passare un valore booleano come secondo argomento al metodo login
. Questo valore indica se desideri la funzionalità "ricordami" per la sessione autenticata. Ricorda, questo significa che la sessione sarà autenticata indefinitamente o finché l’utente non esegue manualmente il logout dall’applicazione:
Auth::login($user, $remember = true);
Se necessario, puoi specificare una guard di autenticazione prima di chiamare il metodo login
:
Auth::guard('admin')->login($user);
Autenticare un Utente tramite ID
Per autenticare un utente utilizzando la chiave primaria del suo record nel database, puoi usare il metodo loginUsingId
. Questo metodo accetta la chiave primaria dell’utente che desideri autenticare:
Auth::loginUsingId(1);
Puoi passare un valore booleano all’argomento remember
del metodo loginUsingId
. Questo valore indica se desideri la funzionalità "ricordami" per la sessione autenticata. Ricorda, questo significa che la sessione sarà autenticata indefinitamente o fino a quando l’utente non effettua manualmente il logout dall’applicazione:
Auth::loginUsingId(1, remember: true);
Autentica un utente una volta
Puoi utilizzare il metodo once
per autenticare un utente nell’applicazione per una singola richiesta. Non verranno utilizzate sessioni o cookie quando chiami questo metodo:
if (Auth::once($credentials)) {
// ...
}
Autenticazione HTTP di Base
L’Autenticazione HTTP di Base offre un modo rapido per autenticare gli utenti della tua applicazione senza creare una pagina "login" dedicata. Per iniziare, aggiungi il middleware auth.basic
a una route. Il middleware auth.basic
è incluso nel framework Laravel, quindi non è necessario definirlo:
Route::get('/profile', function () {
// Solo utenti autenticati possono accedere a questa route...
})->middleware('auth.basic');
Una volta aggiunto il middleware alla route, ti verrà automaticamente chiesto di inserire le credenziali quando accedi alla route dal browser. Di default, il middleware auth.basic
utilizza la colonna email
nella tabella users
del database come "username" dell’utente.
Una Nota su FastCGI
Se usi PHP FastCGI e Apache per servire la tua applicazione Laravel, l’autenticazione HTTP Basic potrebbe non funzionare correttamente. Per risolvere questi problemi, puoi aggiungere le seguenti righe al file .htaccess
della tua applicazione:
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Autenticazione HTTP Basic senza Stato
Puoi utilizzare l’Autenticazione HTTP Basic senza impostare un cookie di identificazione utente nella sessione. Questo è particolarmente utile se scegli di usare l’Autenticazione HTTP per autenticare le richieste all’API della tua applicazione. Per fare ciò, definisci un middleware che chiama il metodo onceBasic
. Se il metodo onceBasic
non restituisce una risposta, la richiesta può essere passata ulteriormente nell’applicazione:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class AuthenticateOnceWithBasicAuth
{
/**
* Gestisci una richiesta in arrivo.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
return Auth::onceBasic() ?: $next($request);
}
}
Successivamente, collega il middleware a una route:
Route::get('/api/user', function () {
// Solo gli utenti autenticati possono accedere a questa route...
})->middleware(AuthenticateOnceWithBasicAuth::class);
Disconnessione
Per disconnettere manualmente gli utenti dalla tua applicazione, puoi utilizzare il metodo logout
fornito dalla facade Auth
. Questo rimuoverà le informazioni di autenticazione dalla sessione dell’utente, in modo che le richieste successive non siano autenticate.
Oltre a chiamare il metodo logout
, è consigliabile invalidare la sessione dell’utente e rigenerare il loro token CSRF. Dopo aver disconnesso l’utente, solitamente reindirizzi l’utente alla radice della tua applicazione:
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
/**
* Disconnetti l'utente dall'applicazione.
*/
public function logout(Request $request): RedirectResponse
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
Invalidare le Sessioni su Altri Dispositivi
Laravel offre anche un meccanismo per invalidare e "disconnettere" le sessioni di un utente attive su altri dispositivi senza invalidare la sessione sul dispositivo corrente. Questa funzionalità è tipicamente utilizzata quando un utente cambia o aggiorna la propria password e si desidera invalidare le sessioni sugli altri dispositivi mantenendo autenticato il dispositivo attuale.
Prima di iniziare, assicurati che il middleware Illuminate\Session\Middleware\AuthenticateSession
sia incluso sulle route che devono ricevere l’autenticazione della sessione. Solitamente, dovresti applicare questo middleware a un gruppo di route in modo che venga applicato alla maggior parte delle route della tua applicazione. Di default, il middleware AuthenticateSession
può essere collegato a una route usando l’alias di middleware auth.session
middleware alias:
Route::middleware(['auth', 'auth.session'])->group(function () {
Route::get('/', function () {
// ...
});
});
Successivamente, puoi utilizzare il metodo logoutOtherDevices
fornito dalla facade Auth
. Questo metodo richiede che l’utente confermi la propria password attuale, che la tua applicazione dovrebbe accettare tramite un modulo di input:
use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($currentPassword);
Quando viene invocato il metodo logoutOtherDevices
, le altre sessioni dell’utente saranno completamente invalidati, il che significa che verranno "disconnessi" da tutte le guard con cui erano precedentemente autenticati.
Conferma Password
Durante lo sviluppo della tua applicazione, potresti avere azioni che richiedono all’utente di confermare la propria password prima che l’azione venga eseguita o prima che l’utente venga reindirizzato a un’area sensibile dell’applicazione. Laravel include middleware integrato per semplificare questo processo. Implementare questa funzionalità richiederà di definire due route: una per mostrare una vista che chiede all’utente di confermare la propria password e un’altra per confermare che la password è valida e reindirizzare l’utente alla destinazione desiderata.
La documentazione seguente spiega come integrare direttamente le funzionalità di conferma password di Laravel; tuttavia, se vuoi iniziare più rapidamente, i Laravel application starter kits includono il supporto per questa funzionalità!
Configurazione
Dopo aver confermato la password, all’utente non verrà richiesto nuovamente di inserirla per tre ore. Tuttavia, puoi impostare il tempo prima che venga chiesta di nuovo la password modificando il valore di password_timeout
nel file di configurazione config/auth.php
della tua applicazione.
Routing
Il Modulo di Conferma della Password
Innanzitutto, definiamo una route per mostrare una vista che richiede all’utente di confermare la propria password:
Route::get('/confirm-password', function () {
return view('auth.confirm-password');
})->middleware('auth')->name('password.confirm');
Come puoi aspettarti, la vista restituita da questa route dovrebbe avere un form contenente un campo password
. Inoltre, puoi includere del testo nella vista che spiega che l’utente sta entrando in un’area protetta dell’applicazione e deve confermare la propria password.
Conferma della Password
Successivamente, definiremo una rotta che gestirà la richiesta del modulo dalla vista "conferma password". Questa rotta sarà responsabile della validazione della password e del reindirizzamento dell’utente alla destinazione desiderata:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redirect;
Route::post('/confirm-password', function (Request $request) {
if (! Hash::check($request->password, $request->user()->password)) {
return back()->withErrors([
'password' => ['La password fornita non corrisponde ai nostri record.']
]);
}
$request->session()->passwordConfirmed();
return redirect()->intended();
})->middleware(['auth', 'throttle:6,1']);
Prima di procedere, esaminiamo questa rotta più da vicino. Innanzitutto, il campo password
della richiesta viene verificato per assicurarsi che corrisponda alla password dell’utente autenticato. Se la password è valida, dobbiamo informare la sessione di Laravel che l’utente ha confermato la propria password. Il metodo passwordConfirmed
imposterà un timestamp nella sessione dell’utente che Laravel può utilizzare per determinare quando l’utente ha confermato l’ultima volta la propria password. Infine, possiamo reindirizzare l’utente alla destinazione desiderata.
Protezione delle Rotte
Assicurati che ogni rotta che richiede una recente conferma della password utilizzi il middleware password.confirm
. Questo middleware è incluso per impostazione predefinita in Laravel e memorizza automaticamente la destinazione desiderata dell’utente nella sessione. In questo modo, dopo aver confermato la password, l’utente viene reindirizzato alla destinazione prevista. Dopo aver memorizzato la destinazione nella sessione, il middleware reindirizza l’utente alla rotta denominata password.confirm
named route:
Route::get('/settings', function () {
// ...
})->middleware(['password.confirm']);
Route::post('/settings', function () {
// ...
})->middleware(['password.confirm']);
Aggiungere Guard Personalizzate
Puoi definire le tue guard di autenticazione utilizzando il metodo extend
sulla facade Auth
. Dovresti inserire la chiamata al metodo extend
all’interno di un provider di servizi. Poiché Laravel include già un AppServiceProvider
, possiamo inserire il codice in quel provider:
<?php
namespace App\Providers;
use App\Services\Auth\JwtGuard;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
// ...
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Auth::extend('jwt', function (Application $app, string $name, array $config) {
// Restituisce un'istanza di Illuminate\Contracts\Auth\Guard...
return new JwtGuard(Auth::createUserProvider($config['provider']));
});
}
}
Come vedi nell’esempio sopra, la callback passata al metodo extend
deve restituire un’implementazione di Illuminate\Contracts\Auth\Guard
. Questa interfaccia contiene alcuni metodi che dovrai implementare per definire una guard personalizzata. Una volta definita la tua guard personalizzata, puoi fare riferimento a essa nella configurazione guards
del file di configurazione auth.php
:
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
Guard di Richiesta Closure
Il modo più semplice per implementare un sistema di autenticazione personalizzato basato su richieste HTTP è utilizzare il metodo Auth::viaRequest
. Questo metodo ti permette di definire rapidamente il processo di autenticazione usando una singola closure.
Per iniziare, chiama il metodo Auth::viaRequest
all’interno del metodo boot
del AppServiceProvider
della tua applicazione. Il metodo viaRequest
accetta come primo argomento il nome di un driver di autenticazione. Questo nome può essere qualsiasi stringa che descriva la tua guard personalizzata. Il secondo argomento passato al metodo deve essere una closure che riceve la richiesta HTTP in arrivo e restituisce un’istanza utente o, se l’autenticazione fallisce, null
:
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Auth::viaRequest('custom-token', function (Request $request) {
return User::where('token', (string) $request->token)->first();
});
}
Una volta definito il tuo driver di autenticazione personalizzato, puoi configurarlo come driver all’interno della configurazione guards
del tuo file di configurazione auth.php
:
'guards' => [
'api' => [
'driver' => 'custom-token',
],
],
Infine, puoi fare riferimento alla guard quando assegni il middleware di autenticazione a una route:
Route::middleware('auth:api')->group(function () {
// ...
});
Aggiungere Provider Utente Personalizzati
Se non stai usando un database relazionale tradizionale per memorizzare i tuoi utenti, dovrai estendere Laravel con un tuo provider di autenticazione utente. Useremo il metodo provider
sulla facade Auth
per definire un provider utente personalizzato. Il resolver del provider utente dovrebbe restituire un’implementazione di Illuminate\Contracts\Auth\UserProvider
:
<?php
namespace App\Providers;
use App\Extensions\MongoUserProvider;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
// ...
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Auth::provider('mongo', function (Application $app, array $config) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return new MongoUserProvider($app->make('mongo.connection'));
});
}
}
Dopo aver registrato il provider usando il metodo provider
, puoi passare al nuovo provider utente nel tuo file di configurazione auth.php
. Prima, definisci un provider
che usa il tuo nuovo driver:
'providers' => [
'users' => [
'driver' => 'mongo',
],
],
Infine, puoi fare riferimento a questo provider nella configurazione dei guards
:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
Il Contratto del User Provider
Le implementazioni di Illuminate\Contracts\Auth\UserProvider
sono responsabili di recuperare un’implementazione di Illuminate\Contracts\Auth\Authenticatable
da un sistema di archiviazione persistente, come MySQL, MongoDB, ecc. Queste due interfacce permettono ai meccanismi di autenticazione di Laravel di funzionare indipendentemente da come i dati utente sono memorizzati o dal tipo di classe usata per rappresentare l’utente autenticato:
Diamo un’occhiata al contratto Illuminate\Contracts\Auth\UserProvider
:
<?php
namespace Illuminate\Contracts\Auth;
interface UserProvider
{
public function retrieveById($identifier);
public function retrieveByToken($identifier, $token);
public function updateRememberToken(Authenticatable $user, $token);
public function retrieveByCredentials(array $credentials);
public function validateCredentials(Authenticatable $user, array $credentials);
public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false);
}
La funzione retrieveById
di solito riceve una chiave che rappresenta l’utente, come un ID auto-incrementante da un database MySQL. L’implementazione di Authenticatable
che corrisponde all’ID dovrebbe essere recuperata e restituita dal metodo.
La funzione retrieveByToken
recupera un utente tramite il suo unico $identifier
e il $token
"remember me", tipicamente memorizzato in una colonna del database come remember_token
. Come nel metodo precedente, l’implementazione di Authenticatable
con un valore di token corrispondente dovrebbe essere restituita da questo metodo.
Il metodo updateRememberToken
aggiorna il remember_token
dell’istanza $user
con il nuovo $token
. Un nuovo token viene assegnato agli utenti dopo un tentativo di autenticazione "remember me" riuscito o quando l’utente effettua il logout.
Il metodo retrieveByCredentials
riceve l’array di credenziali passato al metodo Auth::attempt
quando si tenta di autenticarsi con un’applicazione. Il metodo dovrebbe quindi "interrogare" lo storage persistente sottostante per l’utente che corrisponde a quelle credenziali. Tipicamente, questo metodo esegue una query con una condizione "where" che cerca un record utente con un "username" che corrisponde al valore di $credentials['username']
. Il metodo dovrebbe restituire un’implementazione di Authenticatable
. Questo metodo non dovrebbe tentare di validare la password o autenticare.
Il metodo validateCredentials
dovrebbe confrontare l’utente dato $user
con le $credentials
per autenticare l’utente. Ad esempio, questo metodo utilizzerà tipicamente il metodo Hash::check
per confrontare il valore di $user->getAuthPassword()
con il valore di $credentials['password']
. Questo metodo dovrebbe restituire true
o false
indicando se la password è valida.
Il metodo rehashPasswordIfRequired
dovrebbe rehashare la password dell’utente dato $user
se necessario e supportato. Ad esempio, questo metodo utilizzerà tipicamente il metodo Hash::needsRehash
per determinare se il valore di $credentials['password']
necessita di essere rehashato. Se la password necessita di essere rehashata, il metodo dovrebbe usare il metodo Hash::make
per rehashare la password e aggiornare il record dell’utente nello storage persistente sottostante.
Il Contratto Authenticatable
Ora che abbiamo esplorato ciascuno dei metodi del UserProvider
, diamo un’occhiata al contratto Authenticatable
. Ricorda, i provider utenti devono restituire implementazioni di questa interfaccia dai metodi retrieveById
, retrieveByToken
e retrieveByCredentials
:
<?php
namespace Illuminate\Contracts\Auth;
interface Authenticatable
{
public function getAuthIdentifierName();
public function getAuthIdentifier();
public function getAuthPasswordName();
public function getAuthPassword();
public function getRememberToken();
public function setRememberToken($value);
public function getRememberTokenName();
}
Questa interfaccia è semplice. Il metodo getAuthIdentifierName
deve restituire il nome della colonna della "chiave primaria" per l’utente e il metodo getAuthIdentifier
deve restituire la "chiave primaria" dell’utente. Quando si utilizza un back-end MySQL, probabilmente sarà la chiave primaria auto-incrementante assegnata al record dell’utente. Il metodo getAuthPasswordName
deve restituire il nome della colonna della password dell’utente. Il metodo getAuthPassword
deve restituire la password hashata dell’utente.
Questa interfaccia permette al sistema di autenticazione di funzionare con qualsiasi classe "user", indipendentemente dall’ORM o dallo strato di astrazione di storage che stai utilizzando. Di default, Laravel include una classe App\Models\User
nella directory app/Models
che implementa questa interfaccia.
Rielaborazione Automatica della Password
L’algoritmo di hashing predefinito di Laravel è bcrypt. Il "work factor" per gli hash bcrypt può essere regolato tramite il file di configurazione config/hashing.php
della tua applicazione oppure tramite la variabile d’ambiente BCRYPT_ROUNDS
.
Di solito, il work factor di bcrypt dovrebbe aumentare nel tempo man mano che la potenza di elaborazione della CPU/GPU cresce. Se aumenti il work factor di bcrypt per la tua applicazione, Laravel rielaborerà in modo automatico e senza problemi le password degli utenti quando questi si autenticano tramite i kit di avvio di Laravel o quando autentichi manualmente gli utenti usando il metodo attempt
.
In generale, la rielaborazione automatica delle password non dovrebbe interferire con la tua applicazione; tuttavia, puoi disabilitare questo comportamento pubblicando il file di configurazione hashing
:
php artisan config:publish hashing
Una volta pubblicato il file di configurazione, puoi impostare il valore rehash_on_login
su false
:
'rehash_on_login' => false,
Eventi
Laravel invia una varietà di eventi durante il processo di autenticazione. Puoi definire listeners per uno qualsiasi dei seguenti eventi:
Nome Evento |
---|
Illuminate\Auth\Events\Registered |
Illuminate\Auth\Events\Attempting |
Illuminate\Auth\Events\Authenticated |
Illuminate\Auth\Events\Login |
Illuminate\Auth\Events\Failed |
Illuminate\Auth\Events\Validated |
Illuminate\Auth\Events\Verified |
Illuminate\Auth\Events\Logout |
Illuminate\Auth\Events\CurrentDeviceLogout |
Illuminate\Auth\Events\OtherDeviceLogout |
Illuminate\Auth\Events\Lockout |
Illuminate\Auth\Events\PasswordReset |