No internet connection
  1. Home
  2. JavaScript

Route Guards em Angular

Os Route Guards (guardas de rota) são recursos do Angular que permitem controlar a navegação em rotas. Eles fornecem uma maneira de proteger e controlar o acesso a rotas, permitindo tomar decisões antes de carregar uma rota, como verificar autenticação, permissões, entre outras lógicas de autorização.

Criando um Guard

ng g guard nome_da_guard

Ao executar o comando, irá perguntar qual o método de verificação, aqui se deve escolher CanActivate.

No Angular 17, a forma como se gerencia um Guard, por padrão, mudou. Antes o que seria uma classe que implementa CanActivate Agora é so uma função do tipo CanActivateFn, sendo agora uma função, para injetar dependências dentro do Guard, se usa o inject que vem do @angular/core

import { CanActivateFn, Router } from '@angular/router';
import { inject } from '@angular/core';

export const guardTestGuard: CanActivateFn = (route, state) => {
	const router = inject(Router)
  return true;
};

Antes, os Guards se pareciam com isso:

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AutorizadoGuard implements CanActivate {

  constructor(private routerService: Router){}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
		return true;
}

Como o Guard atua

Antes do usuário conseguir entrar em uma página, caso tenha um Guard naquela rota, o Guard será acionado e baseado na lógica construída nele, irá permitir ou não que o usuário consiga entrar naquela página, uma Gaurd retorna um valor booleano.

Para incluir um Guard em uma rota, é necessário declarar o Guard nele, ou seja, no arquivo de rotas da aplicação, rotas já foram abordadas anteriormente, inclua a propriedade CanActivate que esperará um array de Guard. Por aguardar um array, já é possível concluir que podem ter vários Guards por rota.

import NomeDoGuard from "caminho/do/Guard";

export const routes: Routes = [
    {path:'pg1', component:Pg1Component, canActivated: [NomeDoGuard]}
];

Dentro de um guard é possível fazer requisições para API, a fim de validar se o usuário tem autorização para acessar aquela página, ou só acessar os cookies do navegador e verificar se existe um cookie de sessão ativo.

Usando Guard em várias rotas

Por padrão, o Guard precisa ser incluído em todas as rotas que usam ele, isso pode ser maçante se a aplicação possuir várias rotas, para resolver esse problema, é possível se aproveitar das rotas alinhadas explicadas no tópico de rotas, usando o exemplo que foi usado para a explicação do Layout padrão, ficaria assim:

const routes: Routes = [
  {
    path: '',
    component: LayoutComHeaderComponent,
		canActivate: [AuthGuard] //Apenas essas rotas tem Guard
    children: [
      { path: 'pagina1', component: Pagina1Component },
      { path: 'pagina2', component: Pagina2Component },
      // ... outras rotas com Guard...
    ]
  },
  { path: 'login', component: LoginComponent }, // Rota sem Guard
  { path: 'logout', component: LogoutComponent }, // Rota sem Guard
  { path: '404', component: NotFoundComponent }, // Rota sem Guard
];

Dessa forma, é possível escolher quais rotas precisam de validação de usuário e quais não precisam.

Exemplo de Uso

Será criado um Guard para verificar se existe um item token, válido, no LocalStorage do navegador e se sim o Guard passará, se não, o Guard precisa redirecionar o usuário para a página de login.

AuthService

Primeiro, vamos criar um serviço de autenticação AuthService que verifica se o token está presente e se é válido.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  getToken(): string | null {
    return localStorage.getItem('token');
  }

  isLoggedIn(): boolean {
    const token = this.getToken();
    return !!token; // Retorna true se o token existir
  }
}

Implementando o Route Guard:

Agora, vamos criar um Guard (AuthGuard) que utiliza o serviço AuthService para verificar se o token está presente e se é válido.

export const guardTestGuard: CanActivateFn = (route, state) => {
	const router = inject(Router)
	const authService = inject(AuthService)

  if (this.authService.isLoggedIn()) {
      return true; // O usuário pode acessar a rota
    } else {
      this.router.navigate(['/login']); // Redireciona para a página de login se não estiver autenticado
      return false; // Não permite o acesso à rota
    }
};

Configuração nas Rotas:

Finalmente, configure o AuthGuard nas suas rotas que exigem autenticação.

const routes: Routes = [
	//{...}
  {
    path: 'home',
    component: HomeComponent,
    canActivate: [guardTestGuard] // Protege a rota com o AuthGuard
  },
  // ... outras rotas protegidas ...
];

Referências

  • 0 respostas