L’autenticazione è una delle caratteristiche essenziali delle applicazioni web. I framework web come Laravel offrono agli utenti diversi modi per autenticarsi.

È possibile implementare le funzioni di autenticazione di Laravel in modo rapido e sicuro. Tuttavia, implementare queste funzioni di autenticazione in modo scorretto può essere rischioso perché persone malintenzionate potrebbero sfruttare eventuali falle.

Questa guida spiega tutto ciò che c’è da sapere per iniziare a usare i metodi di autenticazione di Laravel che avete scelto.

Continuate a leggere!

Introduzione all’Autenticazione in Laravel

Laravel introduce moduli composti da “guardie” (guards) e “fornitori” (providers). Le guardie definiscono l’autenticazione dell’utente per ogni richiesta, mentre i fornitori definiscono il recupero dell’utente da un archivio persistente (per esempio un database MySQL).

Definiamo i nostri parametri di autenticazione in un file chiamato config/auth.php. Il file include diverse opzioni per regolare e modificare il comportamento di Laravel in materia di autenticazione.

Per prima cosa, dovete definire le impostazioni predefinite di autenticazione. Questa opzione controlla le opzioni predefinite di autenticazione e di reset della password della vostra applicazione. Potete modificare queste impostazioni predefinite in base alle vostre esigenze, ma sono un inizio perfetto per la maggior parte delle applicazioni.

Successivamente, definite le guardie di autenticazione per la vostra applicazione. In questo caso, la nostra configurazione predefinita usa l’archiviazione della sessione e lo user provider di Eloquent. Tutti i driver di autenticazione hanno uno user provider.

<?php

return [
    /* 
    Defining Authentication Defaults  
    */
    
    'defaults' => [
        'guard' => 'web', 
        'passwords' => 'users',
    ],
    
    /*
    Defining Authentication Guards
   
    Supported: "session"
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
     ],
    
    /*
    Defining User Providers

    Supported: "database", "eloquent"
    */

    'providers' => [
        'users' => [
             'driver' => 'eloquent',
             'model' => App\Models\User::class,
        ], 

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

    /*
    Defining Password Resetting
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
         ],
     ],

     /*
     Defining Password Confirmation Timeout
     */

    'password_timeout' => 10800,
];

In seguito, assicuriamoci che tutti i driver di autenticazione abbiano uno user provider. Questo definisce il modo in cui gli utenti vengono recuperati dal database o da altri meccanismi di archiviazione per conservare i dati degli utenti. Potete configurare più fonti che rappresentano ogni modello o tabella se avete più tabelle o modelli di utenti. Queste fonti possono essere assegnate a qualsiasi altra guardia di autenticazione che avete definito.

Gli utenti possono anche voler reimpostare la propria password. Potete specificare più configurazioni di reimpostazione della password se avete più tabelle o modelli di utenti nell’applicazione e volete impostazioni separate in base agli specifici tipi di utenti. Il tempo di scadenza è il numero di minuti di validità di ogni token di reset. Questa funzione di sicurezza fa sì che i token abbiano vita breve, in modo da avere meno tempo per essere indovinati. Potete modificare questo valore in base alle vostre esigenze.

Infine, dovete definire l’intervallo di tempo prima che la conferma della password si esaurisca e all’utente venga richiesto di reinserire la password nella schermata di conferma. Per impostazione predefinita, il timeout dura tre ore.

Tipi di Metodi di Autenticazione in Laravel

Non esiste un metodo di autenticazione perfetto per ogni scenario, ma conoscerlo vi aiuterà a prendere decisioni migliori. Vi servirà anche sapere come Laravel si sta evolvendo con le nuove funzionalità di Laravel 9. Questo rende il nostro lavoro di sviluppo molto più semplice quando cambiamo modalità di autenticazione.

Autenticazione Basata su Password

Si tratta di un metodo rudimentale per autenticare un utente, ancora utilizzato da migliaia di organizzazioni, ma considerando lo sviluppo attuale, sta diventando chiaramente obsoleto.

I fornitori devono imporre l’implementazione di password complesse, garantendo al contempo un attrito minimo per l’utente finale.

Il funzionamento è piuttosto semplice: l’utente inserisce il nome e la password e se nel database c’è una corrispondenza tra questi due dati, il server decide di autenticare la richiesta e di permettere all’utente di accedere alle risorse per un periodo di tempo predefinito.

Autenticazione Basata su Token

Questa metodologia prevede che all’utente venga rilasciato un token unico al momento della verifica.

Avendo questo token, l’utente può accedere alle risorse pertinenti. Il privilegio è attivo fino alla scadenza del token.

Mentre il token è attivo, l’utente non deve usare alcun nome utente o password, ma quando recupera un nuovo token, questi due elementi vengono richiesti.

I token sono oggi ampiamente utilizzati in diversi scenari, poiché sono entità stateless che contengono tutti i dati di autenticazione.

Fornire un modo per separare la generazione del token dalla sua verifica offre ai vendor una grande flessibilità.

Autenticazione a Più Fattori

Come suggerisce il nome, implica l’utilizzo di almeno due fattori di autenticazione, elevando la sicurezza offerta.

A differenza dell’autenticazione a due fattori che coinvolge solo due fattori, questo metodo può coinvolgerne due, tre, quattro e anche di più.

L’implementazione tipica di questo metodo prevede l’utilizzo di una password, dopodiché l’utente riceve un codice di verifica sul proprio smartphone. I fornitori che implementano questo metodo devono fare attenzione ai falsi positivi e alle interruzioni di rete, che possono diventare un grosso problema se si scala rapidamente.

Come Implementare l’Autenticazione in Laravel

Questa sezione vi insegnerà diversi modi per autenticare gli utenti della vostra applicazione. Alcune librerie come Jetstream, Breeze e Socialite contengono tutorial gratuiti su come utilizzarle.

Autenticazione Manuale

Iniziamo con la registrazione degli utenti e la creazione delle route necessarie in routes/web.php.

Creeremo due percorsi, uno per visualizzare il modulo e uno per registrarsi:

use App\Http\Controllers\Auth\RegisterController;
use Illuminate\Support\Facades\Route;

/*
Web Routes 

Register web routes for your app's RouteServiceProvider 
in a group containing the "web" middleware
*/

Route::get('/register', [RegisterController::class, 'create']);
Route::post('/register', [RegisterController::class, 'store']);

E creeremo il controller necessario per questi percorsi:

php artisan make:controller Auth/RegisterController -r

Ora aggiornate il codice come segue:

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use illuminate\Htpp\Request;

class RegisterController extends Controller
{
    public function create()
    {
        return view('auth.register');
    }

    public function store(Request $request)
    {
    }
}

Il controller ora è vuoto e restituisce una vista da registrare. Creiamo questa vista in resources/views/auth e chiamiamola register.blade.php.

Vista Laravel blade per la registrazione degli utenti.
Vista Laravel blade per la registrazione degli utenti.

Ora che tutto è a posto, dovremmo visitare il nostro percorso /register e vedere il seguente modulo:

Modulo di registrazione per l'autenticazione manuale.
Modulo di registrazione per l’autenticazione manuale.

Ora che possiamo visualizzare un modulo che l’utente può compilare e ottenere i dati, dobbiamo ottenere i dati dell’utente, convalidarli e memorizzarli nel database se tutto è a posto. In questo caso dovreste usare una transazione del database per assicurarvi che i dati inseriti siano completi.

Useremo la funzione di convalida delle richieste di Laravel per assicurarci che tutte e tre le credenziali siano richieste. Dobbiamo assicurarci che l’email abbia un formato email e sia unica nella tabella users e che la password sia confermata e abbia un minimo di 8 caratteri:

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class RegisterController extends Controller
{
    public function store(Request $request)
    {
        /* 
        Validation
        */
        $request->validate([
            'name' => 'required',
            'email' => 'required|email|unique:users',
            'password' => 'required|confirmed|min:8',
        ]);

        /*
        Database Insert
        */
        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        return back();
    }

    public function create()
    {
        return view('auth.register');
    }
}

Ora che i nostri input sono stati convalidati, qualsiasi cosa che non sia in linea con la nostra convalida darà luogo a un errore che verrà visualizzato nel modulo:

Esempio di input non valido per la registrazione
Esempio di input non valido per la registrazione

Supponendo di aver creato un account utente nel metodo store, vogliamo anche effettuare il login dell’utente. Ci sono due modi per farlo. Possiamo farlo manualmente o usare la facade Auth.

Dopo che l’utente ha effettuato il login, non dobbiamo riportarlo alla schermata di registrazione ma a una nuova pagina, come una bacheca o una homepage. Questo è ciò che faremo qui:

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;

class RegisterController extends Controller
{
    public function store(Request $request)
    {
        /* 
        Validation
        */
        $request->validate([
            'name' => 'required',
            'email' => 'required|email|unique:users',
            'password' => 'required|confirmed|min:8',
        ]);

        /*
        Database Insert
        */
        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        Auth::login($user);

        return redirect(RouteServiceProvider::HOME);
    }

    public function create()
    {
        return view('auth.register');
    }
}

Ora che l’utente si è registrato e ha effettuato il login -n, dobbiamo assicurarci che possa disconnettersi in modo sicuro.

Laravel suggerisce di invalidare la sessione e di rigenerare il token di sicurezza dopo il logout. Ed è proprio quello che faremo. Inizieremo creando una nuova route /logout con il metodo destroy di LogoutController:

use App\Http\Controllers\Auth\RegisterController;
use App\Http\Controllers\Auth\LogoutController;
use Illuminate\Support\Facades\Route;

/*
Web Routes

Here is where you can register web routes for your application. These
routes are loaded by the RrouteServiceProvider with a group which
contains the "web" middleware group. Now create something great!
*/

Route::get('/register', [RegisterController::class, 'create']);
Route::post('/register', [RegisterController::class, 'store']);
Route::post('/logout', [Logoutcontroller::class, 'destroy'])
    ->middleware('auth');

Il passaggio del logout attraverso il middleware auth è molto importante. Gli utenti non devono poter accedere al percorso se non hanno effettuato il login.

Ora create un controller come abbiamo fatto in precedenza:

php artisan make:controller Auth/LogoutController -r

Possiamo assicurarci di ottenere la richiesta come parametro nel metodo destroy. Disconnettiamo l’utente attraverso la facade Auth, invalidiamo la sessione e rigeneriamo il token, quindi reindirizziamo l’utente alla homepage:

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LogoutController extends Controller
{
    public function destroy(Request $request)
    { 
        Auth::logout();

        $request->session()->invalidate();
        $request->session()->regenerateToken();
 
        return redirect('/');
     }
}

Memorizzare gli Utenti

La maggior parte, se non tutte, le moderne applicazioni web prevedono una casella di controllo “remember me” (ricordami) nel loro modulo di login.

Se vogliamo fornire la funzionalità “remember me”, possiamo passare un valore booleano come secondo argomento del metodo attempt.

Se il valore è valido, Laravel manterrà l’utente autenticato a tempo indeterminato o fino a quando non verrà disconnesso manualmente. La tabella degli utenti deve includere la colonna remember_token (è per questo che rigeneriamo i token), dove memorizzeremo il nostro token “remember me”.

La migrazione predefinita degli utenti la include già.

Prima di tutto, dovete aggiungere il campo Remember me al vostro modulo:

Aggiunta del campo Remember me.
Aggiunta del campo Remember me.

Dopodiché, prendete le credenziali dalla richiesta e usatele nel metodo attempt della facade Auth.

Se l’utente viene ricordato, effettueremo il login e lo reindirizzeremo alla nostra homepage. In caso contrario, lanceremo un errore:

public function store(Request $request)
{
    $credentials = $request->only('email', 'password');

    if (Auth::attempt($credentials, $request->filled('remember'))) {
        $request->session()->regenerate();

        return redirect()->intended('/');
    }

    return back()->withErrors([
        'email' => 'The provided credentials do not match our records.',
    ]);
}

Resettare le Password

La maggior parte delle applicazioni web offre agli utenti la possibilità di reimpostare la propria password.

Creeremo un’altra route per la password dimenticata e creeremo il controller come abbiamo fatto finora. Inoltre, aggiungeremo una route per il link di reimpostazione della password che contiene il token per l’intero processo:

Route::post('/forgot-password', [ForgotPasswordLinkController::class, 'store']);
Route::post('/forgot-password/{token}', [ForgotPasswordController::class, 'reset']);

All’interno del metodo store, prenderemo l’email dalla richiesta e la convalideremo come abbiamo fatto.

Dopodiché, possiamo usare il metodo sendResetLink dall’interfaccia della password.

Infine, come risposta, vogliamo restituire lo stato che spiega se l’invio del link è riuscito o se ci sono errori:

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;

class ForgotPasswordLinkController extends Controller
{
    public function store(Request $request)
    {
        $request->validate([
             'email' => 'required|email',
        ]);

        $status = Password::sendResetLink(
            $request->only('email');
        );

        return $status === Password::RESET_LINK_SENT
            ? back()->with('status', __($status))
            : back()->withInput($request->only('email'))->withErrors(['email' => __($status)]);
     }
}

Ora che il link per la reimpostazione è stato inviato all’email dell’utente, dobbiamo occuparci della logica di ciò che accade dopo.

Otterremo il token, l’email e la nuova password nella richiesta e li convalideremo.

Dopodiché, possiamo usare il metodo di reset della facade della password per lasciare che Laravel si occupi di tutto il resto dietro le quinte.

La password sarà sempre sottoposta a hash per mantenerla sicura.

Alla fine, verificheremo se la password è stata resettata e, in caso affermativo, reindirizzeremo l’utente alla schermata di login con un messaggio di successo. In caso contrario, visualizzeremo un errore che indica che non è stato possibile resettare la password:

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;

class ForgotPasswordController extends Controller
{
    public function reset(Request $request)
    {
        $request->validate([
            'token' => 'required',
            'email' => 'required|email',
            'password' => 'required|string|confirmed|min:8',
        ]);

        $status = Password::reset(
            $request->only('email', 'password', 'password_confirmation', 'token'),
            function ($user) use ($request) {
                $user->forceFill(
                    'password' => Hash::make($request->password),
                    'remember_token' => Str::random(60)
                ])->save();
            }
        );

        return $status == Password::PASSWORD_RESET
            ? redirect()->route('login')->with('status', __($status))
            : back()->withInput($request->only('email'))->withErrors(['email' => __($status)]);
    }
}

Laravel Breeze

Laravel Breeze è una semplice implementazione delle funzioni di autenticazione di Laravel: login, registrazione, reset della password, verifica via email e conferma della password. Potete usarlo per implementare l’autenticazione nella vostra nuova applicazione Laravel.

Installazione e Configurazione

Dopo aver creato la vostra Applicazione Laravel, tutto ciò che dovete fare è configurare il database, eseguire le migrazioni e installare il pacchetto laravel/breeze tramite composer:

composer require laravel/breeze --dev

Dopodiché, eseguite i seguenti passaggi:

php artisan breeze:install

Così pubblicherete le vostre viste di autenticazione, le route, i controller e le altre risorse che utilizza. Dopo questo passaggio, avrete il controllo completo di tutto ciò che Breeze mette a disposizione.

Ora dobbiamo rendere la nostra applicazione al frontend, quindi installeremo le nostre dipendenze JS (che utilizzeranno @vite):

npm install

:

npm run dev

In seguito, i link per il login e la registrazione dovrebbero essere presenti nella vostra homepage e tutto dovrebbe funzionare senza problemi.

Laravel Jetstream

Laravel Jetstream estende Laravel Breeze con utili funzioni e altri stack di frontend.

Fornisce login, registrazione, verifica dell’email, autenticazione a due fattori, gestione delle sessioni, supporto API tramite Sanctum e gestione opzionale del team.

Quando installate Jetstream dovete scegliere tra Livewire e Inertia per il frontend. Per quanto riguarda il backend, usa Laravel Fortify, un backend di autenticazione “headless”, agnostico rispetto al frontend per Laravel.

Installazione e Configurazione

Lo installeremo tramite Composer nel nostro progetto Laravel:

composer require laravel/jetstream

Dopodiché eseguiamo il comando php artisan jetstream:install [stack], che accetta gli argomenti [stack] Livewire o Inertia. Potete passare l’opzione --teams per abilitare la funzione dei team.

Questo installerà anche Pest PHP per i test.

Infine, dobbiamo eseguire il rendering del frontend della nostra applicazione utilizzando il seguente comando:

npm install
npm run dev

Laravel Fortify

Laravel Fortify è un’implementazione di autenticazione backend che è agnostica rispetto al frontend. Non è necessario usare Laravel Fortify per implementare le funzioni di autenticazione di Laravel.

Viene utilizzato anche in starter kit come Breeze e Jetstream. Potete anche usare Fortify standalone, che è solo un’implementazione del backend. Se lo usate da solo, il vostro frontend deve chiamare le route di Fortify.

Installazione e Configurazione

Possiamo installare Fortify tramite Composer:

composer require laravel/fortify

Ora dobbiamo pubblicare le risorse di Fortify:

php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"

A questo punto, creeremo una nuova cartella app/Actions oltre al nuovo FortifyServiceProvider, al file di configurazione e alle migrazioni del database.

Infine, eseguite:

php artisan migrate

Oppure:

php artisan migrate:fresh

E il vostro Fortify è pronto per essere utilizzato.

Laravel Socialite

Laravel include una semplice funzione di autenticazione degli utenti basata su OAuth. Supporta i login social tramite Facebook, Twitter, LinkedIn, Google, Bitbucket, GitHub e GitLab.

Installazione

Possiamo installarlo tramite Composer:

composer require laravel/socialite

Installazione e Utilizzo

Dopo averlo installato, dobbiamo aggiungere le credenziali del provider OAuth che la nostra applicazione utilizza. Le aggiungeremo in config/services.php per ogni servizio.

Nella configurazione, dobbiamo abbinare la chiave ai servizi precedenti. Alcune di queste chiavi sono:

  • facebook
  • twitter (per OAuth 1.0)
  • twitter-oauth-2 (per OAuth 2.0)
  • linkedin
  • google
  • github
  • gitlab
  • bitbucket

La configurazione di un servizio può assomigliare a questa:

'google' => [
    'client_id' => env("GOOGLE_CLIENT_ID"),
    'client_secret' => env("GOOGLE_CLIENT_SECRET"),
    'redirect' => "http://example.com/callback-url",
],

Autenticare gli Utenti

Per questa azione avremo bisogno di due route, una per reindirizzare l’utente al provider OAuth:

use Laravel\Socialite\Facades\Sociliate;

Route::get('/auth/redirect', function () {
    return Socialite::driver('google')->redirect();
});

e una per il callback dal provider dopo l’autenticazione:

use Laravel\Socialite\Facades\Socialite;

Route:;get('/auht/callback', function () {
    $user = Socialite::driver('google')->user();

    // Getting the user data
    $user->token;
});

Socialite fornisce il metodo di reindirizzamento e la facade reindirizza l’utente al provider OAuth, mentre il metodo utente esamina la richiesta in arrivo e recupera le informazioni dell’utente.

Dopo aver ricevuto il nostro utente, dobbiamo verificare se esiste nel nostro database e autenticarlo. Se non esiste, creeremo un nuovo record per rappresentare l’utente:

use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;

Route::get('/auth/callback', function () {
   /*
   Get the user
   */
   $googleUser = Socialite::driver('google')->user();
   
   /*
   Create the user if it does not exist
   Update the user if it exists
   
   Check for google_id in database
   */
   $user = User::updateOrCreate([
       'google_id' => $googleUser->id,
   ], [
       'name' => $googleUser->name,
       'email' => $googleUser->email,
       'google_token' => $googleUser->token,
       'google_refresh_token' => $googleUser->refreshToken,
   ]);

   /*
   Authenticates the user using the Auth facade
   */
    Auth::login($user);
   
    return redirect('/dashboard');
});

Se vogliamo limitare gli ambiti di accesso dell’utente, possiamo usare il metodo scopes, che includeremo nella richiesta di autenticazione. Questo metodo unirà tutti gli ambiti specificati in precedenza con quelli specificati.

Un’alternativa è quella di usare il metodo setScopes che sovrascrive ogni altro ambito esistente:

use Laravel\Socialite\Facades\Socialite;

return Socialite::driver('google')
    ->scopes(['read:user', 'write:user', 'public_repo'])
    ->redirect();

return Socialite::driver('google')
    ->setScopes(['read:user', 'public_repo'])
    ->redirect();

Ora che sappiamo tutto e come richiamare un utente dopo il callback, vediamo alcuni dei dati che possiamo ottenere da esso.

L’utente OAuth1 ha token e tokenSecret:

$user = Socialite::driver('google')->user();

$token = $user->token;
$tokenSecret = $user->tokenSecret;

L’utente OAuth2 fornisce token, refreshToken e expiresIn:

$user = Socialite::driver('google')->user();

$token = $user->token;
$refreshToken = $user->refreshToken;
$expiresIn = $user->expiresIn;

Sia OAuth1 che OAuth2 forniscono getId, getNickname, getName, getEmail e getAvatar:

$user = Socialite::driver('google')->user();

$user->getId();
$user->getNickName();
$user->getName();
$user->getEmail();
$user->getAvatar();

E se vogliamo ottenere i dettagli dell’utente da un token (OAuth 2) o da un token segreto (OAuth 1), Socialite fornisce due metodi per farlo: userFromToken e userFromTokenAndSecret:

use Laravel\Socialite\Facades\Socialite;

$user = Socialite::driver('google')->userFromToken($token);
$user = Socialite::driver('twitter')->userFromTokenAndSecret($token, $secret);

Laravel Sanctum

Laravel Sanctum è un sistema di autenticazione leggero per SPA (Single Page Application) e applicazioni mobili. Consente agli utenti di generare più token API con scopi specifici. Questi ambiti specificano le azioni consentite da un token.

Utilizzi

Sanctum si può usare per rilasciare token API all’utente senza le complessità di OAuth. Questi token hanno in genere scadenze lunghe, anche di anni, ma possono essere revocati e rigenerati dall’utente in qualsiasi momento.

Installazione e Configurazione

Possiamo installarlo tramite Composer:

composer require laravel/sanctum

E dobbiamo pubblicare i file di configurazione e di migrazione:

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

Ora che abbiamo generato i nuovi file di migrazione, dobbiamo migrarli:

php artisan migrate:fresh

Come Rilasciare i Token API

Prima di rilasciare i token, il nostro modello Utente deve usare il tratto Laravel\Sanctum\HasApiTokens:

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticable
{
    use HasApiTokens;
}

Quando abbiamo l’utente, possiamo rilasciare un token chiamando il metodo createToken, che restituisce un’istanza Laravel\Sanctum\NewAccessToken.

Possiamo chiamare il metodo plainTextToken sull’istanza NewAccessToken per vedere il valore SHA-256 in chiaro del token.

Consigli e Buone Pratiche per l’Autenticazione in Laravel

Invalidare le Sessioni su Altri Dispositivi

Come abbiamo detto in precedenza, l’invalidazione della sessione è fondamentale quando l’utente si disconnette, ma dovrebbe essere un’opzione disponibile anche per tutti i dispositivi posseduti.

Questa funzione viene solitamente utilizzata quando l’utente cambia o aggiorna la propria password e vogliamo invalidare la sua sessione da qualsiasi altro dispositivo.

Con la facade Auth, si tratta di un compito facile da realizzare. Considerando che il percorso che stiamo utilizzando ha i metodi auth e auth.session middleware, possiamo usare il metodo statico logoutOtherDevices della facade:

Route::get('/logout', [LogoutController::class, 'invoke'])
    ->middleware(['auth', 'auth.session']);

use Illuminate\Support\Facades\Auth;

Auth::logoutOtherDevices($password);

Configurazione con Auth::routes()

Il metodo routes della facade Auth è solo un supporto per generare tutte le route necessarie per l’autenticazione degli utenti.

I percorsi includono Login (Get, Post), Logout (Post), Register (Get, Post) e Password Reset/Email (Get, Post).

Quando chiamate il metodo sulla facade, questo esegue le seguenti operazioni:

public static function routes(array $options = [])
{
    if (!static::$app->providerIsLoaded(UiServiceProvider::class)) {
        throw new RuntimeException('In order to use the Auth:;routes() method, please install the laravel/ui package.');
    }
   
    static::$app->make('router')->auth($options);
}

Ci interessa sapere cosa succede quando il metodo statico viene chiamato sul router. Questo può essere complicato a causa del funzionamento delle facades, ma il metodo seguente viene chiamato in questo modo:

/**
Register the typical authentication routes for an application.

@param array $options
@return void
*/
public function auth(array $options = [])
{
    // Authentication Routes...
    $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
    $this->post('login', 'Auth\LoginController@login');
    $this->post('logout', 'Auth\LoginController@logout')->name('logout');

    // Registration Routes...
    if ($options['register'] ?? true) {
        $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
        $this->post('register', 'Auth\RegisterController@register');
    }
   
    // Password Reset Routes...
    if ($options['reset'] ?? true) {
        $this->resetPassword();
    }

    // Email Verification Routes...
    if ($options['verify'] ?? false) {
        $this->emailVerification();
    }
}   

Per impostazione predefinita, genera tutti i percorsi oltre a quello di verifica dell’email. Avremo sempre i percorsi Login e Logout, ma gli altri possono essere controllati attraverso l’array delle opzioni.

Se vogliamo avere solo login/logout e registrazione, possiamo passare il seguente array di opzioni:

$options = ["register" => true, "reset" => false, "verify" => false];

Proteggere le Route e le Protezioni Personalizzate

Vogliamo assicurarci che alcune route siano accessibili solo agli utenti autenticati e questo si può fare chiamando il metodo middleware sulla facade Route o concatenando il metodo middleware su di essa:

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

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

Questa protezione assicura che le richieste in arrivo siano autenticate.

Conferma della Password

Per una maggiore sicurezza del sito web, spesso si desidera confermare la password di un utente prima di procedere con qualsiasi altra attività.

Dobbiamo definire un percorso dalla vista Conferma password per gestire la richiesta. Questo percorso convaliderà e reindirizzerà l’utente alla destinazione prevista. Allo stesso tempo, ci assicureremo che la nostra password venga confermata nella sessione. Per impostazione predefinita, la password deve essere riconfermata ogni tre ore, ma è possibile modificarla nel file di configurazione config/auth.php:

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' => ['The provided password does not match our records.']
        ]);
    }

    $request->session()->passwordConfirmed();

    return redirect()->intended();
})->middleware(['auth']);

Contratto Authenticable

Il contratto Authenticable che si trova in Illuminate\Contracts\Auth definisce un modello di ciò che la facade UserProvider deve implementare:

namespace Illuminate\Contracts\Auth;

interface Authenticable 
{
    public function getAuthIdentifierName();
    
    public function getAuthIdentifier();
    
    public function getAuthPassord();
  
    public function getRememberToken();

    public function setRememberToken($value);
  
    public function getrememberTokenName();
}

L’interfaccia permette al sistema di autenticazione di lavorare con qualsiasi classe “utente” che la implementi.

Questo vale indipendentemente dai livelli ORM o di archiviazione utilizzati. Per impostazione predefinita, Laravel ha l’App\Models\User che implementa questa interfaccia, come si può vedere anche nel file di configurazione:

return [
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
     ],
];

Eventi di Autenticazione

Ci sono molti eventi che vengono inviati durante l’intero processo di autenticazione.

A seconda dei vostri obiettivi, potete collegare dei listener a questi eventi nel vostro sito EventServiceProvider.

Un elenco di listener Laravel generati per il nostro servizio di autenticazione
Un elenco di listener Laravel generati per il nostro servizio di autenticazione

Creare Rapidamente Nuovi Utenti

La creazione rapida di un nuovo utente può essere effettuata tramite App\User:

$user = new App\User();
$user->password = Hash::make('strong_password');
$user->email = '[email protected]';
$user->name = 'Username';
$user->save();

Oppure attraverso il metodo create static della facade User:

User::create([
 'password' => Hash::make('strong-password'),
 'email' => '[email protected]',
 'name' => 'username'
]);

Riepilogo

L’ecosistema di Laravel offre numerosi starter kit implementare nella vostra app un sistema di autenticazione, come Breeze e Jetstream. Sono altamente personalizzabili perché il codice viene generato da noi e possiamo modificarlo a piacimento, usandolo all’occorrenza come template.

Ci sono molti problemi di sicurezza per la complessità dell’autenticazione, ma tutti questi problemi possono essere risolti grazie agli strumenti disponibili per Laravel. Questi strumenti sono personalizzabili e semplici da usare.

Per le vostre applicazioni, scegliete il nostro veloce ed efficiente servizio di hosting Laravel. E con la nostra prova gratuita, potrete osservare la vostra applicazione Laravel in azione senza rischi.

Coman Cosmin

Cosmin Coman è uno scrittore e sviluppatore di tecnologia con oltre 3 anni di esperienza. Oltre a scrivere per Kinsta, ha collaborato alla ricerca presso strutture di fisica nucleare e università. Esperto di tecnologia e integrato nella comunità, propone sempre soluzioni innovative.