Blog

Autenticazione con React ed il jwt di laravel 9

Tempo di lettura: 11 minuti

In questo tutorial vi spiego come realizzare un’autenticazione con React ed il Jwt di laravel 9.

Per proteggere l’API di autenticazione dell’utente in Laravel useremo la libreria di terze parti  tymondesigns/jwt-auth.

Nella seconda parte del tutorial realizzeremo la parte front end con React dove andremo ad autenticarci utilizzando l’API realizzata precedentemente.

Che cosa è il json web token

Il json web token (jwt) è uno standard aperto (rfc 7519) e rappresenta un metodo compatto e autonomo per la trasmissione sicura di informazioni tra le parti come oggetto JSON.

La firma digitale rende affidabile e verificata la trasmissione degli stessi tramite jwt. Questi si basano su un algoritmo segreto HMAC o su una coppia di chiavi pubblica/privata tramite RSA o ECDSA.

Autenticazione con React ed il jwt di laravel 9: requisiti

Prima di continuare mi aspetto che conosciate di già la Libreria React nella sua ultima versione, difatti faremo uso degli hooks e Laravel , anche in questo caso faremo uso dell’ultima versione , cioè la 9.

A dire il vero avevo già scritto un’articolo in merito anche se un pò diverso in quanto in questo caso non utilizzeremo lo scaffolding di React in Laravel ma gli stessi saranno separati risiedendo in due server diversi.

Installa laravel

Come recita la documentazione di Laravel aprite un terminale , fatelo puntare su una vostra directory a piacere e digitate :

composer create-project laravel/laravel backend --prefer-dist

bene ora attendete il tempo necessario affinchè venga creato il progetto.

Una volta terminato all’interno della vostra directory vi troverete una cartella di nome backend, ok ora dovete realizzare il database.

Realizza e connettiti al database

Per poter realizzare e connetterci ad un db utilizzerò il web server locale Laragon , voi utilizzatene pure uno a piacere. Se state utilizzando Laragon apritelo e fate click su terminale, quindi digitate:

mysql -u root -p

la -u sta per user che nel mio caso in locale è root e la -p sta per password. Fate invio, in password: fate semplicemente invio in quanto in locale non la abbiamo configurata.

se tutto è ok potete digitare:

Create database OMDB_DB;

Avete appena realizzato il vostro database, potete uscire dal terminale.

Aprite il vostro progetto con il vostro Ide a piacere quindi aprite il file .env e configurate LA PARTE RELATIVA AL DATABASE come di seguito:

...
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=OMDB_DB
DB_USERNAME=root
DB_PASSWORD=
...

Aggiungi la tabella utente al database

Una volta creato il database possiamo fare la nostra prima migration aggiungendo la tabella User allo stesso, aprite il terminale e digitate:

php artisan migrate

Se aprite il database noterete la tabella appena creata:

Installa e configura il pacchetto di autenticazione JWT

tymondesigns/jwt-auth è un pacchetto JWT di terze parti e consente l’autenticazione dell’utente utilizzando il JWT in laravel e lumen in modo sicuro.

Per scaricarlo da terminale digitate:

composer require tymon/jwt-auth

Una volta scaricato aprite il file config/app.php ed includete il provider di servizi laravel all’interno di provider nell’array:

'providers' => [
    ....
    ....
    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],
'aliases' => [
    ....
    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
    ....
],

quindi pubblichiamo la configurazione del package digitando il seguente comando da terminale:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

ora osiamo generare una secret key per gestire la crittografia del token:

php artisan jwt:secret

se aprite il file .env potete notare una nuova riga che certifica la corretta generazione della key:

...
JWT_SECRET=wsdrFDtNU32B5qsEbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
...

Configura lo User Model

Aprite il model User in app/models/User.php e definite due nuovi metodi per poter utilizzare il package di Tymon, come di seguito:

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Tymon\JWTAuth\Contracts\JWTSubject;

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

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
    public function getJWTIdentifier() {
        return $this->getKey();
    }
    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims() {
        return [];
    }
}

 

dove con getJWTIdentifier si ottiene l’identificatore che verrà poi archiviato nella rivendicazione dell’oggetto del jwt.

getJWTCustomClaims restituisce una matrice di valori chiave , contenente attestazioni personalizzate da aggiungere al jwt.

Configura l’autenticazione protetta

Aprite il file config/auth.php ed impostiamo la guardia predefinita su api e, di conseguenza, a questi viene detto di utilizzare il driver jwt:

...
return [

    'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],


    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
            'hash' => false,
        ],
    ],
...

Realizza il controller per l’autenticazione

Nel controller relativo all’autenticazione definiremo la logica principale per il processo di autenticazione sicura. Da terminale digitate:

php artisan make:controller AuthController

inserisci il seguente codice all’interno del file app/Http/Controllers/AuthController.php:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Validator;

class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct() {
        $this->middleware('auth:api', ['except' => ['login', 'register']]);
    }
    /**
     * Get a JWT via given credentials.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request){
    	$validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'password' => 'required|string|min:6',
        ]);
        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }
        if (! $token = auth()->attempt($validator->validated())) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
        return $this->createNewToken($token);
    }
    /**
     * Register a User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function register(Request $request) {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|between:2,100',
            'email' => 'required|string|email|max:100|unique:users',
            'password' => 'required|string|confirmed|min:6',
        ]);
        if($validator->fails()){
            return response()->json($validator->errors()->toJson(), 400);
        }
        $user = User::create(array_merge(
                    $validator->validated(),
                    ['password' => bcrypt($request->password)]
                ));
        return response()->json([
            'message' => 'User successfully registered',
            'user' => $user
        ], 201);
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout() {
        auth()->logout();
        return response()->json(['message' => 'User successfully signed out']);
    }
    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh() {
        return $this->createNewToken(auth()->refresh());
    }
    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function userProfile() {
        return response()->json(auth()->user());
    }
    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function createNewToken($token){
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60,
            'user' => auth()->user()
        ]);
    }
}

Il middleware auth:api viene utilizzato all’interno del costruttore della classe; non è possibile accedere ai metodi all’interno del controller di autenticazione senza disporre di un token valido. Inoltre possiamo passare il nome delle funzioni all’interno del middleware che vogliamo siano escluse dall’obbligo del token.

Metodo login

Il metodo login consente l’autenticazione dell’utente mediante password ed email, in risposta genera un token di autorizzazione a patto che trovi l’utente all’interno del db. Nel caso contrario restituisce un errore.

Metodo register

Con il  metodo register inseriamo un nuovo utente nel db tramite dei campi con relativa validazione.

Metodo logout

Con il metodo logout cancelliamo il token dell’utente loggato, molto semplicemente.

Metodo Refresh

Questo crea un nuovo Token.

Metodo userProfile

Esegue il rendering dei dati dell’utente connesso che abbia un token valido.

Metodo createNewToken

Questa funzione crea un nuovo token di autenticazione dopo la sua scadenza o eliminazione.

Aggiungi le routes per l’autenticazione

Trattandosi di una API REST i percorsi ,o routes, dell’applicazione relativi all’autenticazione vanno inseriti all’interno del file routes/api.php e non in web.php. Quindi aprite il primo e modificate come di seguito:

<?php

use App\Http\Controllers\AuthController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

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

Route::group([
    'middleware' => 'api',
    'prefix' => 'auth'
], function ($router) {
    Route::post('/login', [AuthController::class, 'login']);
    Route::post('/register', [AuthController::class, 'register']);
    Route::post('/logout', [AuthController::class, 'logout']);
    Route::post('/refresh', [AuthController::class, 'refresh']);
    Route::get('/user-profile', [AuthController::class, 'userProfile']);
});

Testare l’API di autenticazione con POSTMAN

Prima di passare alla realizzazione del front-end è sempre buona norma testare l’API REST. A tal proposito utilizzeremo postman, per cui vi consiglio di scaricarlo ed installarlo se non lo avete.

Autenticazione con React ed il jwt di laravel 9

Registrazione

Aprite postman  e nella barra degli indirizzi digitate l’indirizzo relativo al metodo register definito nel file routes/api.php, non vi scordate prima di servire l’applicazione:

Autenticazione con React ed il jwt di laravel 9

ok selezionate il metodo POST per la richiesta HTTP, quindi selezionate body, form-data e sotto inserite i nomi dei campi definiti nella request con i relativi valori. Una volta fatto fate click su SEND.

Se tutto ok verrà restituito un oggetto di tipo json con le info relative all’utente registrato.

Login

Una volta aggiunto un utente al database possiamo testare anche la fase di autenticazione e rendersi conto se in effetti viene creato un token. Sempre in postman aggiungete una nuova scheda cliccando su +:

nella barra degli indirizzi questa volta digitate http://127.0.0.1:8000/api/auth/login, selezionate ancora una volta il metodo POST

Autenticazione con React ed il jwt di laravel 9

se tutto è andato a buon fine vi verrà restituito una serie di informazioni sempre in json compreso il nostro token.

UserProfile

In postman aggiungete una nuova  scheda ed inserite l’indirizzo http://127.0.0.1:8000/api/auth/user-profile, questa volta selezionate il metodo HTTP GET. Selezionate Authorization , in TYPE selezionate Bearer Token, nella finestra a destra incollate il token restituito dopo aver fatto il login:

Autenticazione con React ed il jwt di laravel 9

in basso ,se avete incollato il token correttamente, vi verrà restituito le info relativamente al titolare del token.

Metodo refresh

Per aggiornare un token è necessario averne uno valido. Aggiungete una nuova scheda in postman ed inserite l’indirizzo http://127.0.0.1:8000/api/auth/refresh, selezionate questa volta il metodo POST, poi il resto rimane invariato rispetto al metodo userProfile:

se prestate attenzione ogni volta che fate click su SEND il token si aggiorna.

Metodo logout

Aggiungete una nuova scheda in postman , digitate l’indirizzo http://127.0.0.1:8000/api/auth/logout, metodo POST, poi tutto rimane invariato rispetto al refresh purchè inseriate l’ultimo token aggiornato nell’apposito campo:

Autenticazione con React ed il jwt di laravel 9

fate click su SEND ed il token verrà cancellato.

Conclusione

Nella prima parte del tutorial abbiamo realizzato una REST API con Laravel9 relativa ad un’autenticazione sicura mediante JWT. Prima di procedere alla realizzazione del front end con React (cosa che faremo nella seconda parte del tutorial) abbiamo giustamente testato il tutto con Postman.

Puoi scaricare e/o visionare  il codice su GitHub.

Se volete Approfondire le conoscenze su Laravel potete seguire il  corso completo su Udemy sempre scontato a 9.99/12.99 € , inoltre, nel momento in cui non foste soddisfatti, avete la possibilità di ottenere il rimborso completo dello stesso entro 30 giorni dalla data di acquisto!

Lucio Ticali

Chi è ?

Lucio Ticali è un Web & App developer con la passione per il web marketing,si occupa anche di tecniche di indicizzazione del sito e di promozione dello stesso (SEO e SEM).

Lascia la tua opinione