Proteggere le rotte è un argomento piuttosto frequente nello sviluppo di applicazioni web che prevedono un accesso tramite login. Lo strumento che consente di discriminare l’utenza, in gergo viene definito come Guard.
Questo termine, tradotto dall’inglese, significa guardia e calza perfettamente con quello di cui stiamo parlando.
L’esigenza che spinge lo sviluppatore a proteggere una determinata view è probabilmente dovuta ad una suddivisione dei privilegi dell’utenza che ha accesso al sito. Le view, e di conseguenza le relative rotte che devono essere configurate dietro una pagina di login, hanno necessità di negare l’accesso all’utenza guest.
Dietro un login
Gestire un form di login è una operazione piuttosto semplice che non prevede l’uso di package particolari o service dedicati. Possiamo limitarci ad immaginare il componente Login come una semplice view con un form con due input: username e password.
I dati immessi dall’utente con l’operazione di submit vengono inviati tramite chiamata HTTP ad un endpoint che, nel caso in cui username e password risultassero corretti, risponderà con il classico codice di stato HTTP 200. Il componente Login confermerà l’avvenuto collegamento.
Il guard Angular viene spesso implementato e di conseguenza gestito tramite l’interfaccia dedicata CanActivate, che consente di verificare i privilegi dell’utente e quindi negare o consentire l’accesso ad una determinata rotta. Ipotizziamo di avere definito questo routing:
… import {AuthGuard} from './auth.service'; const appRoutes: Routes = [ { path: 'login', component: LoginComponent }, { path: 'private', component: PrivateComponent, canActivate: [AuthGuard] } ];
canActive è il parametro che, nella specifica rotta, consente di invocare la nostra classe AuthGuard affinché questa faccia la guardia alla rotta private. La classe AuthGuard potrebbe essere qualcosa di questo tipo:
import { Injectable } from '@angular/core'; import { CanActivate } from '@angular/router'; import { LoginService } from './login/login.service';
@Injectable() export class AuthGuard implements CanActivate { constructor(private l: LoginService) {} canActivate() { if(this.l.user){ return true; }else{ return false; } } }
AuthGuard deve implementare l’interfaccia CanActive che si occupa di verificare la presenza del metodo canActive. Il suddetto metodo viene invocato simultaneamente alla richiesta di accesso alla rotta da parte dell’utenza. Quello che faremo in questo metodo sarà restituire true se l’accesso sarà consentito o false nel caso in cui sarà negato.
Nella fattispecie è importante tenere traccia del login effettuato tramite un servizio dedicato che lavora integrandosi al componente di login. Il servizio LoginService, in questo caso, fornirà l’oggetto user il quale, se valorizzato, significa che l’utente ha effettuato il login e quindi sarà abilitato alla navigazione della rotta private.
Altre interfacce
Oltre a CanActive, esistono altre due interfacce: CanDeactivate e CanActivateChild, che rispettivamente invocano i metodi canActivateChild, e canDeactivate.
L’interfaccia CanDeactivate viene invocata quando si sta per lasciare una rotta e risulterà parecchio utile in diversi contesti, come per esempio la compilazione di form complessi. Il funzionamento di CanActivateChild è identico a CanActive, con la differenza che viene usata per le rotte figlie.
È bene non dimenticare che il servizio AuthGuard deve essere dichiarato come providers tramite il decoratore NgModule. Buona programmazione!
Abbiamo anche intervistato Vincenzo Giacchina all’indomani dell’uscita del suo Sviluppare applicazioni con Angular edito da Apogeo.