Come usare le Route Guards con il routing di Angular

  • Di
  • 2025-02-13 - 3 minuti
banner

Immagina di voler mettere in sicurezza la tua applicazione Angular e di voler gestire l’accesso ad una serie di route solo agli utenti autorizzati: come fare?

Basta usare le Route Guard. 😎

TOC

Cosa sono le Route Guard

Angular Route Guards ci aiuta a impedire all’utente di accedere a determinate parti delle applicazioni in condizioni specifiche. Possiamo anche utilizzarlo per eseguire alcune azioni prima di navigare verso un percorso o di mandare l’utente in un’altra pagina.

Queste risorse funzionano da controllo sull’accesso e supportano diversi casi d’uso: una “guardia” puΓ² attivare o disattivare l’accesso a una specifica rotta, oppure valutare l’accesso a un componente “figlio” di quello richiesto. Vediamo qualche esempio!

Come funzionano

Per il momento, per spiegarne il funzionamento in Angular, ci concentreremo sul tipo piΓΉ comune: CanActivate.

Per prima cosa, creiamo una route guard che, tramite l’autenticazione verifichi se l’utente ha effettuato l’accesso.

// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from './auth.service'; 

@Injectable({
    providedIn: 'root'
})
export class AuthGuard implements CanActivate {
    constructor(private authService: AuthService, private router: Router) {}

    canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): boolean {
        if (this.authService.isAuthenticated()) {
            return true; 
        } else {
            this.router.navigate(['/login']); 
            return false;
        }
    }
}

Successivamente, andiamo a lavorare sulla configurazione del routing, specificando le “regole” di accesso: per esempio, in questo caso lasciamo che l’accesso alla pagina principale sia aperto a tutti gli utenti, mentre il componente dashboard solo a chi ha eseguito il login.

Questo viene verificato tramite l’AuthGuard definito in precedenza che, restituendo un valore booleano, specifica ad Angular se l’utente puΓ² accedere o meno alla pagina richiesta.

L’ultima route il cui path Γ¨ ** serve a specificare che qualsiasi richiesta di accesso a rotte diverse da quelle specificate o richieste che provengono da utenti senza i permessi, devono rimandare al componente PageNotFound:

// app-routing.module.ts:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home.component';
import { DashboardComponent } from './dashboard.component';
import { AuthGuard } from './auth.guard';
import { PageNotFoundComponent } from './pageNotFound/pageNotFound.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
  { path: 'login', component: LoginComponent },
  { path: 'pageNotFound', component: PageNotFound },
  { path: '**', redirectTo: 'pageNotFound' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

Un esempio di AuthService in Angular Γ¨ il seguente, che include il metodo isAuthenticated. Questo servizio gestisce l’autenticazione utente e fornisce metodi per controllare lo stato di autenticazione.

// auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
export class AuthService {
    private apiUrl = 'https://mybackend/auth'; 
    private userSubject: BehaviorSubject<any>;
    public user: Observable<any>;

    constructor(private http: HttpClient, private router: Router) {
        this.userSubject = new BehaviorSubject<any>(JSON.parse(localStorage.getItem('user') || '{}'));
        this.user = this.userSubject.asObservable();
    }

    login(username: string, password: string): Observable<any> {
        return this.http.post<any>(`${this.apiUrl}/login`, { username, password })
            .pipe(tap(user => {
                localStorage.setItem('user', JSON.stringify(user));
                this.userSubject.next(user);
            }));
    }

    isAuthenticated(): boolean {
        const user = this.userSubject.value;
        return user && user.token ? true : false; 
    }

    logout(): void {
        localStorage.removeItem('user');
        this.userSubject.next(null);
        this.router.navigate(['/login']);
    }
}

Giusto per dare qualche informazione di piΓΉ sugli oggetti utilizzati in questo esempio, parliamo di BehaviorSubject: userSubject Γ¨ un BehaviorSubject che contiene le informazioni dell’utente corrente. Si inizializza con qualsiasi dato utente esistente dal localStorage.

Grazie al metodo di login che invia una richiesta all’API con le credenziali dell’utente, in caso di successo, il servizio memorizza i dati utente restituiti (incluso un token JWT) nello storage locale e aggiorna l’oggetto userSubject.

Allo stesso modo, il metodo di logout cancella i dati dell’utente dallo storage locale e torna alla pagina di login una volta che l’utente si Γ¨ disconnesso.

Post correlati

TheRedCode.it - Il mondo #tech a piccoli #bit

Partners

Community, aziende e persone che supportano attivamente il blog

Logo di Codemotion
Logo di GrUSP
Logo di Python Milano
Logo di Schrodinger Hat
Logo di Python Biella Group
Logo di Fuzzy Brains
Logo di Django Girls
Logo di Improove
Logo del libro open source
Logo di NgRome
Logo de La Locanda del Tech
Logo di Tomorrow Devs
Logo di Coderful
Logo di VueSchool

Non perderti gli ultimi aggiornamenti, iscriviti a TheRedCode Digest!

La tecnologia corre, e tu devi correre piΓΉ veloce per rimanere sempre sul pezzo! πŸš€

Riceverai una volta al mese (o anche meno) con codici sconto per partecipare agli eventi del settore, quiz per vincere dei gadget e i recap degli articoli piΓΉ interessanti pubblicati sul blog

Ci sto!

#TheRedComics

Edizione di Gennaio - Buon Anno nuovo!

A cura di Sophie Aiello, copy di Chiara Romano

Fumetto di dicembre di Sophie Aiello, Copy di Chiara Romano

Vuoi diventare #tech content creator? πŸ–ŠοΈ

Se vuoi raccontare la tua sul mondo #tech con dei post a tema o vuoi condividere la tua esperienza con la community, sei nel posto giusto! πŸ˜‰

Manda una mail a collaborazioni[at]theredcode.it con la tua proposta e diventa la prossima penna del blog!

Ma sì, facciamolo!