Authenticatie is een van de meest kritische en essentiële features van webapplicaties. Webframeworks als Laravel bieden vele manieren om gebruikers te authenticeren.

Je kunt Laravel authenticatiefeatures vaak snel en veilig implementeren. Het slecht implementeren van deze authenticatiefuncties kan echter riskant zijn, omdat kwaadwillenden er misbruik van kunnen maken.

Deze handleiding leert je alles wat je moet weten om aan de slag te gaan met de door jou gekozen Laravel authenticatiemethoden.

Lees verder!

Een inleiding tot Laravel authenticatie

Laravel bevat modules die bestaan uit “guards” en “providers“. Guards definiëren de authenticatie van gebruikers voor elk verzoek, en providers definiëren het ophalen van gebruikers uit persistente opslag (b.v. MySQL database).

We definiëren onze authenticatieparameters in een bestand met de naam config/auth.php. Het bevat verschillende opties om het authenticatiegedrag van Laravel aan te passen.

Eerst moet je de standaardinstellingen van authenticatie definiëren. Deze optie regelt de standaard authenticatie “guard” en resetopties van het wachtwoord van je applicatie. Je kunt deze standaardinstellingen naar behoefte wijzigen, maar ze vormen een perfecte start voor de meeste applicaties.

Vervolgens definieer je de authenticatiemonitoring voor je applicatie. Hier gebruikt onze standaardconfiguratie sessieopslag en de Eloquent userprovider. Alle authenticatiestuurprogramma’s hebben een userprovider.

<?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' => AppModelsUser::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,
];

Later zorgen we ervoor dat alle authenticatiestuurprogramma’s een userprovider hebben. Deze definieert hoe de gebruikers worden opgehaald uit je database of andere opslagmechanismen om de gegevens van je gebruikers te persisteren. Je kunt meerdere bronnen configureren die elk model of tabel vertegenwoordigen, als je meerdere gebruikerstabellen of -modellen hebt. Deze bronnen kunnen worden toegewezen aan alle extra authenticatieguards die je hebt gedefinieerd.

Gebruikers kunnen ook hun wachtwoorden opnieuw willen instellen. Hiervoor kun je meerdere wachtwoordresetconfiguraties opgeven als je meer dan één gebruikerstabel of -model in de applicatie hebt en aparte instellingen wilt op basis van de specifieke gebruikerstypes. De vervaltijd is het aantal minuten dat elk resettoken geldig is. Deze beveiligingsfeature houdt de tokens kort geldig, zodat ze minder tijd hebben om geraden te worden. Je kunt dit naar behoefte veranderen.

Uiteindelijk moet je de tijd bepalen voordat een wachtwoordbevestiging uitvalt, en de gebruiker gevraagd wordt zijn wachtwoord opnieuw in te voeren via het bevestigingsscherm. Standaard duurt de timeout drie uur.

Soorten Laravel authenticatiemethoden

Er is geen perfecte manier die werkt bij elk type scenario waarin je wilt authenticeren, maar als je ze kent kun je betere beslissingen nemen. Het is daarnaast ook belangrijk te weten hoe Laravel zich heeft ontwikkeld wat betreft nieuwe features in Laravel 9. Dit maakt ons werk als developers veel gemakkelijker bij het wisselen en kiezen van authenticatiemethoden.

Authenticatie met wachtwoord

Als simpele manier om een gebruiker te authenticeren, wordt het nog steeds gebruikt door duizenden organisaties, maar gezien de huidige ontwikkeling is het duidelijk verouderd aan het raken.

Providers moeten complexe wachtwoordimplementaties afdwingen en tegelijkertijd zorgen voor minimale wrijving voor de eindgebruiker.

Het werkt vrij eenvoudig, de gebruiker voert de naam en het wachtwoord in, en als er in de database een overeenkomst is tussen die twee, besluit de server het verzoek te authenticeren en de gebruiker toegang te geven tot de resources voor een vooraf bepaalde tijd.

Authenticatie met een token

Bij deze methode krijgt de gebruiker na verificatie een uniek token.

Met dit token heeft de gebruiker toegang tot de relevante resources. Het privilege is actief totdat het token verloopt.

Zolang het token actief is, hoeft de gebruiker geen gebruikersnaam of wachtwoord te gebruiken, maar bij het ophalen van een nieuw token zijn die twee wel nodig.

Tokens worden tegenwoordig veel gebruikt in allerlei scenario’s, omdat het stateless entiteiten zijn die alle authenticatiegegevens bevatten.

Het bieden van een manier om tokengeneratie en tokenverificatie te scheiden geeft vendors veel flexibiliteit.

Multi-factor authenticatie

Zoals de naam al aangeeft, houdt dit in dat er minstens twee authenticatiefactoren worden gebruikt, waardoor de beveiliging wordt verhoogd.

In tegenstelling tot authenticatie met twee factoren, waarbij slechts twee factoren worden gebruikt, kan deze methode twee, drie, vier, en meer..

Bij deze methode wordt meestal een wachtwoord gebruikt, waarna de gebruiker een verificatiecode op zijn smartphone ontvangt. Leveranciers die deze methode implementeren moeten uitkijken voor valse positieven en netwerkuitval, die grote problemen kunnen worden bij snelle opschaling.

Zo implementeer je Laravel authenticatie

In dit gedeelte leer je meerdere manieren om de gebruikers van je applicatie te authenticeren. Sommige bibliotheken zoals Jetstream, Breeze en Socialite hebben gratis tutorials over hoe ze te gebruiken.

Handmatige authenticatie

Te beginnen met het registreren van gebruikers en het maken van de benodigde routes in routes/web.php.

We zullen twee routes maken, één om het formulier te bekijken en één om te registreren:

 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']);

En de controller maken die daarvoor nodig is:

php artisan make controller Auth/RegisterController -r

Werk nu de code als volgt bij:

namespace AppHttpControllersAuth;

use AppHttpControllersController;
use illuminateHtppRequest;

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

    public function store(Request $request)
    {
    }
}

De controller is nu leeg en geeft een view terug om te registreren. Laten we die view maken in resources/views/auth en het register.blade.php noemen .

Laravel blade view voor het registreren van gebruikers.
Laravel blade view voor het registreren van gebruikers.

Nu met alles op zijn plaats, zouden we onze /register route moeten bezoeken en het volgende formulier moeten zien:

Registratieformulier voor handmatige verificatie.
Registratieformulier voor handmatige verificatie.

Nu we een formulier kunnen weergeven dat een gebruiker kan invullen en de gegevens ervoor kunnen krijgen, moeten we de gegevens van de gebruikers ophalen, valideren, en dan in de database opslaan als alles in orde is. Hier moet je een databasetransactie gebruiken om er zeker van te zijn dat de gegevens die je invoegt compleet zijn.

We zullen de verzoekvalidatiefeature van Laravel gebruiken om ervoor te zorgen dat alle drie de inloggegevens vereist zijn. We moeten ervoor zorgen dat de e-mail een e-mailformat heeft en uniek is in de tabel users en dat het wachtwoord bevestigd is en minimaal acht tekens telt:

namespace AppHttpControllersAuth;

use AppHttpControllersController;
use IlluminateFoundationAuthUser;
use IlluminateHttpRequest;
use IlluminateSupportFacadesHash;

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');
    }
}

Nu onze invoer gevalideerd is, zal alles wat tegen onze validatie ingaat een fout opleveren die in het formulier wordt weergegeven:

Voorbeeld van ongeldige invoer voor registratie.
Voorbeeld van ongeldige invoer voor registratie.

Ervan uitgaande dat we een gebruikersaccount hebben aangemaakt in de methode store, willen we de gebruiker ook aanmelden. Er zijn twee manieren waarop we dat kunnen doen. We kunnen het handmatig doen of Auth facade gebruiken.

Nadat de gebruiker is ingelogd, moeten we hem niet terugbrengen naar het Register scherm, maar naar een nieuwe pagina, zoals een dashboard of homepage. Dat is wat we hier gaan doen:

namespace AppHttpControllersAuth;

use AppHttpControllersController;
use AppProvidersRouteServiceProvider;
use IlluminateFoundationAuthUser;
use IlluminateHttpRequest;
use IlluminateSupportFacadesAuth;
use IlluminateSupportFacadesHash;

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');
    }
}

En nu we een gebruiker hebben geregistreerd en ingelogd -n, moeten we ervoor zorgen dat hij veilig kan uitloggen.

Laravel stelt voor dat we de sessie ongeldig maken en het token voor de veiligheid regenereren na een afmelding. En dit is precies wat we gaan doen. We beginnen met het maken van een nieuwe /logout route met behulp van de methodedestroy van de LogoutController :

use AppHttpControllersAuthRegisterController;
use AppHttpControllersAuthLogoutController;
use IlluminateSupportFacadesRoute;

/*
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');

Het doorgeven van het uitloggen via de auth middleware is erg belangrijk. De gebruikers moeten geen toegang krijgen tot de route als ze niet ingelogd zijn.

Maak nu een controller zoals we eerder deden:

php artisan make:controller Auth/LogoutController -r

We kunnen ervoor zorgen dat we het verzoek als parameter krijgen in de methode destroy. We loggen de gebruiker uit via de Auth facade, maken de sessie ongeldig en regenereren het token, en sturen de gebruiker dan door naar de homepage:

namespace AppHttpControllersAuth;

use AppHttpControllersController;
use IlluminateHttpRequest;
use IlluminateSupportFacadesAuth;

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

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

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

Gebruikers onthouden

De meeste, zo niet alle, moderne webapplicaties bieden een “remember me” checkbox op hun aanmeldingsformulier.

Als we een “remember me” functionaliteit willen bieden, kunnen we een booleaanse waarde doorgeven als tweede argument aan de attempt methode.

Bij geldigheid zal Laravel de gebruiker voor onbepaalde tijd geauthenticeerd houden, of totdat hij handmatig wordt uitgelogd. De gebruikerstabel moet de kolom string remember_token (daarom regenereren we de tokens) bevatten, waarin we ons “remember me” token opslaan.

De standaardmigratie voor gebruikers bevat die al.

Om te beginnen moet je het Remember Me veld toevoegen aan je formulier:

Remember me veldformulier
Remember me veldformulier

En daarna haal je de credentials uit het verzoek en gebruik je ze op de attempt methode op de Auth facade.

Als de gebruiker onthouden moet worden, loggen we hem in en sturen hem door naar onze homepage. Anders geven we een foutmelding:

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

Wachtwoorden resetten

De meeste webapplicaties bieden tegenwoordig manieren voor gebruikers om hun wachtwoord opnieuw in te stellen.

We zullen nog een route maken voor het vergeten wachtwoord en de controller maken zoals we deden. Daarnaast zullen we een route toevoegen voor de link om het wachtwoord te resetten, die het token voor het hele proces bevat:

Route::post('/forgot-password', [ForgotPasswordLinkController::class, 'store']);

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

Binnen de store methode nemen we de e-mail uit het verzoek en valideren die zoals we deden.

Hierna kunnen we de methode sendResetLink uit de wachtwoordfacade gebruiken.

En dan willen we als antwoord de status teruggeven als het gelukt is om de link te versturen, of anders fouten:

namespace AppHttpControllersAuth;

use AppHttpControllersController;
use IlluminateHttpRequest;
use IlluminateSupportFacadesPassword;

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)]);
     }
}

Nu de resetlink naar de e-mail van de gebruiker is gestuurd, moeten we zorgen voor de logica van wat er daarna gebeurt.

We krijgen het token, de e-mail en het nieuwe wachtwoord in het verzoek en valideren die.

Hierna kunnen we de reset methode van de wachtwoordfacade gebruiken om Laravel de rest achter de schermen te laten regelen.

We gaan het wachtwoord altijd hashen om het veilig te houden.

Aan het eind controleren we of het wachtwoord gereset is, en als dat zo is, sturen we de gebruiker door naar het inlogscherm met een succesmelding. Anders geven we een foutmelding dat het niet gereset kon worden:

namespace AppHttpControllersAuth;

use AppHttpControllersController;
use IlluminateHttpRequest;
use IlluminateSupportFacadesHash;
use IlluminateSupportFacadesPassword;
use IlluminateSupportStr;

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 is een eenvoudige implementatie van Laravel authenticatiefeatures: inloggen, registratie, wachtwoordreset, e-mailverificatie en wachtwoordbevestiging. Je kunt het gebruiken om authenticatie te implementeren in je nieuwe Laravel applicatie.

Installatie en setup

Na het maken van je Laravel applicatie hoef je alleen nog maar je database te configureren, je migraties uit te voeren, en het laravel/breeze pakket te installeren via composer:

composer require laravel/breeze --dev

Voer hierna het volgende uit:

php artisan breeze:install

Dit zal je authenticatie views, routes, controllers en andere resources die het gebruikt publiceren. Na deze stap heb je volledige controle over alles wat Breeze biedt.

Nu moeten we onze applicatie renderen naar de frontend, dus installeren we onze JS dependencies (die @vite zullen gebruiken):

npm install

:

npm run dev

Hierna zouden inlog- en registratielinks op je homepage moeten staan, en zou alles soepel moeten werken.

Laravel Jetstream

Laravel Jetstream breidt Laravel Breeze uit met handige features en andere frontend stacks.

Het geeft je aanmelding, registratie, e-mailverificatie, twee-factor authenticatie, sessiebeheer, API ondersteuning via Sanctum, en optioneel teambeheer.

Je moet bij de installatie van Jetstream kiezen tussen Livewire en Inertia aan de frontend. Aan de backend gebruikt het Laravel Fortify, een frontend agnostische, “headless” authenticatie backend voor Laravel.

Installatie en setup

We installeren het via composer in ons Laravel Project:

composer require laravel/jetstream

Hierna voeren we het commando php artisan jetstream:install [stack] uit, dat [stack] argumenten Livewire of Inertia accepteert. Je kunt de optie --teams doorgeven om de teams feature in te schakelen.

Dit zal ook Pest PHP installeren om te testen.

En tenslotte moeten we de frontend van onze applicatie renderen met het volgende:

npm install
npm run dev

Laravel Fortify

Laravel Fortify is een backend authenticatie-implementatie die frontend agnostisch is. Je hoeft Laravel Fortify niet te gebruiken om de authenticatiefeatures van Laravel te implementeren.

Het wordt ook gebruikt in starterkits als Breeze en Jetstream. Je kunt Fortify ook standalone gebruiken, wat slechts een backend implementatie is. Als je het standalone gebruikt, moet je frontend de Fortify routes callen.

Installatie en setup

We kunnen Fortify installeren via composer:

composer require laravel/fortify

Nu moeten we de resources van Fortify publiceren:

php artisan vendor:publish --provider="LaravelFortifyFortifyServiceProvider"

Hierna maken we een nieuwe app/Actions map aan, naast de nieuwe FortifyServiceProvider, het configuratiebestand en de databasemigraties.

Voer tot slot uit:

php artisan migrate

Of:

php artisan migrate:fresh

En je Fortify is klaar voor gebruik.

Laravel Socialite

Laravel bevat een eenvoudige, op OAuth gebaseerde gebruikersauthenticatiefeature. Deze ondersteunt sociale logins via Facebook, Twitter, LinkedIn, Google, Bitbucket, GitHub en GitLab.

Installatie

We kunnen het installeren via composer:

composer require laravel/socialite

Installatie en gebruik

Nadat we het geïnstalleerd hebben, moeten we de referenties toevoegen voor de OAuth provider die onze applicatie gebruikt. We voegen ze toe in config/services.php voor elke dienst.

In de configuratie moeten we de sleutel afstemmen op de vorige diensten. Enkele van die sleutels zijn:

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

Een dienstconfiguratie kan er als volgt uitzien:

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

Gebruikers authenticeren

Voor deze actie hebben we twee routes nodig, één om de gebruiker door te sturen naar de OAuth provider:

use LaravelSocialiteFacadesSociliate;

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

En één voor de callback van de provider na authenticatie:

use LaravelSocialiteFacadesSocialite;

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

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

Socialite levert de redirect methode, en de facade stuurt de gebruiker door naar de OAuth provider, terwijl de gebruikersmethode het inkomende verzoek onderzoekt en de gebruikersinformatie ophaalt.

Nadat we onze gebruiker hebben ontvangen, moeten we controleren of hij bestaat in onze database en hem authenticeren. Als hij niet bestaat, maken we een nieuw record aan om de gebruiker te vertegenwoordigen:

use AppModelsUser;
use IlluminateSupportFacadesAuth;
use LaravelSocialiteFacadesSocialite;

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');
});

Als we de toegangsscopes van de gebruiker willen beperken, kunnen we de methode scopes gebruiken, die we opnemen in het authenticatieverzoek. Dit zal alle eerder opgegeven scopes samenvoegen met de opgegeven scopes.

Een alternatief hiervoor is het gebruik van de methode setScopes, die elke andere bestaande scoop overschrijft:

use LaravelSocialiteFacadesSocialite;

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

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

Nu we alles weten en weten hoe we een gebruiker kunnen krijgen na de callback, laten we eens kijken naar enkele gegevens die we daaruit kunnen halen.

OAuth1 Gebruiker heeft token en tokenSecret:

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

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

OAuth2 biedt token, refreshToken, en expiresIn:

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

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

Zowel OAuth1 als OAuth2 bieden getId, getNickname, getName, getEmail, en getAvatar:

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

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

En als we gebruikersgegevens uit een token (OAuth 2) of een token en secret (OAuth 1) willen halen, biedt Socialite hiervoor twee methoden: userFromToken en userFromTokenAndSecret:

use LaravelSocialiteFacadesSocialite;

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

Laravel Sanctum

Laravel Sanctum is een licht authenticatiesysteem voor SPA’s (Single Page Applications) en mobiele apps. Het laat gebruikers meerdere API tokens genereren met specifieke scopes. Deze scopes specificeren toegestane acties door een token.

Gebruik

Sanctum kan worden gebruikt om API tokens aan de gebruiker te verstrekken zonder de fijne kneepjes van OAuth. Die tokens hebben meestal lange verlooptijden, zoals jaren, maar kunnen op elk moment door de gebruiker worden herroepen en geregenereerd.

Installatie en setup

We kunnen het installeren via composer:

composer require laravel/sanctum

En we moeten de configuratie- en migratiebestanden publiceren:

php artisan vendor:publish --provider="LaravelSanctumSanctumServiceProvider"

Nu we nieuwe migratiebestanden hebben gegenereerd, moeten we ze migreren:

php artisan migrate:fresh

Zo geef je API tokens uit

Voor het uitgeven van tokens moet ons User model de LaravelSanctumHasApiTokens trait gebruiken:

use LaravelSanctumHasApiTokens;

class User extends Authenticable
{
    use HasApiTokens;
}

Als we de gebruiker hebben, kunnen we een token uitgeven door de methode createToken aan te roepen, die een LaravelSanctumNewAccessToken instance teruggeeft.

We kunnen de methode plainTextToken aanroepen op de instance NewAccessToken om de SHA-256 platte tekstwaarde van het token te zien.

Tips en best practices voor Laravel authenticatie

Sessies op andere apparaten ongeldig maken

Zoals we eerder hebben besproken is het ongeldig maken van de sessie cruciaal als de gebruiker uitlogt, maar dat zou ook beschikbaar moeten zijn als optie voor alle apparaten die eigendom zijn.

Deze feature wordt meestal gebruikt als de gebruiker zijn wachtwoord wijzigt of bijwerkt, en we zijn sessie ongeldig willen maken vanaf elk ander apparaat.

Met de Auth facade is dit eenvoudig te realiseren. Aangezien de route die we gebruiken de auth en auth.session middleware heeft, kunnen we de logoutOtherDevices statische methode van de façade gebruiken:

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

use IlluminateSupportFacadesAuth;

Auth::logoutOtherDevices($password);

Configuratie met Auth::routes()

De routes methode van de Auth facade is slechts een helper om alle routes te genereren die nodig zijn voor de gebruikersauthenticatie.

De routes zijn Login (Get, Post), Logout (Post), Register (Get, Post), en Password Reset/Email (Get, Post).

Wanneer je de methode op de facade aanroept, doet deze het volgende:

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);
}

We zijn geïnteresseerd in wat er gebeurt als de statische methode op de router wordt gecalld. Dit kan lastig zijn vanwege het feit hoe facades werken, maar de volgende methode die wordt gecalld is als volgt:

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

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

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

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

Standaard genereert het alle routes behalve die van de e-mailverificatie. We zullen altijd de Login en Logout routes hebben, maar de andere kunnen we regelen via de opties array.

Als we alleen login/logout en registreren willen, kunnen we de volgende opties array doorgeven:

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

Routes en custom guards beschermen

We willen ervoor zorgen dat sommige routes alleen toegankelijk zijn voor geauthenticeerde gebruikers en dat kan snel door ofwel de middleware methode op de Route facade te callen, ofwel de middleware methode erop te chainen:

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

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

Deze guard zorgt ervoor dat inkomende verzoeken worden geauthenticeerd.

Wachtwoordbevestiging

Voor extra beveiliging van de website wil je vaak het wachtwoord van een gebruiker bevestigen voordat je verder gaat met een andere taak.

We moeten een route definiëren vanuit de “bevestig wachtwoord” weergave om het verzoek af te handelen. Deze zal de gebruiker valideren en doorsturen naar de beoogde bestemming. Tegelijkertijd zorgen we ervoor dat ons wachtwoord bevestigd verschijnt in de sessie. Standaard moet het wachtwoord elke drie uur opnieuw bevestigd worden, maar dit kan veranderd worden in het configuratiebestand in config/auth.php:

use IlluminateHttpRequest;
use IlluminateSupportFacadesHash;
use IlluminateSupportFacadesRedirect;

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']);

Authenticable contract

Het Authenticable contract in IlluminateContractsAuth definieert een blueprint van wat de UserProvider facade moet implementeren:

namespace IlluminateContractsAuth;

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

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

De interface laat het authenticatiesysteem werken met elke “user” klasse die deze implementeert.

Dit geldt ongeacht welke ORM of opslaglagen worden gebruikt. Standaard heeft Laravel de AppModelsUser die deze interface implementeert, en dit is ook te zien in het configuratiebestand:

return [
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => AppModelsUser::class,
        ],
     ],
];

Authenticatie events

Er zijn tal van events die worden verzonden tijdens het hele authenticatieproces.

Afhankelijk van je doelen kun je listeners aan die events koppelen in je EventServiceProvider .

Laravel Listeners
Een lijst van Laravel listeners gegenereerd voor onze authenticatiedienst

Snel nieuwe gebruikers aanmaken

Snel een nieuwe gebruiker aanmaken kan via de AppUser:

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

Of via de create static methode op de User facade:

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

Samenvatting

Het Laravel ecosysteem heeft veel starterkits om je app aan de gang te krijgen met een authenticatiesysteem, zoals Breeze en Jetstream. Ze zijn in hoge mate aanpasbaar omdat de code aan onze kant wordt gegenereerd, en we kunnen hem zoveel aanpassen als we willen, en hem zo nodig als blauwdruk gebruiken.

Er zijn veel beveiligingsproblemen met betrekking tot authenticatie en de fijne kneepjes daarvan, maar die kunnen allemaal eenvoudig worden opgelost met de tools die Laravel biedt. Deze tools zijn in hoge mate aanpasbaar en gemakkelijk te gebruiken.

Deploy je Laravel apps snel en efficiënt met onze snelle Laravel hostingdienst. Zie je app in actie met een gratis trial.

Coman Cosmin

Cosmin Coman is a technology writer and developer with over 3 years of experience. Apart from writing for Kinsta, he has assisted in research at nuclear physics facilities and universities. Tech-savvy and integrated into the community, he always comes up with innovative solutions.