You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

2 Días
14 Hrs
15 Min
36 Seg

Conoce a los Guardianes

19/25
Resources

An application will have N number of routes, but it is possible that many of them have access restrictions only for administrators or certain user roles.

In these cases, the Guards come to help us to give security to our routes.

How to secure Routes

With the help of the Angular CLI, you can create your first guard with the command ng generate guard <guard-name> or in its short form ng g g <guard-name>.

1. Creating the first guard

When using this command, it will ask us a question about which interface you want it to implement by default:

CLI Angular Guards.png

Each option has different functionality for each Guard type. Choose the first option called CanActivate.

When you auto-generate the code, you will see your first Guard looking like this.

// modules/shared/guards/admin.guard.tsimport { Injectable } from '@angular/core';import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root'})export class AdminGuard implements CanActivate {  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean>| boolean { return true; } } }

A Guard can return a boolean, a promise with a boolean or an observable, also with a boolean. Depending on the logic you have to apply for the case, either synchronous or asynchronous.

2. Importing the guard

Now import the new Guard the routing of your application.

// app-routing.module.tsimport { AdminGuard } from './modules/shared/guards/admin.guard';const routes: Routes = [ { path: '', loadChildren: () => import('./modules/website/website.module').then(m => m.WebsiteModule), data: { preload: true }, }, { path: 'cms', loadChildren: () => import('./modules/cms/cms.module').then(m => m.CmsModule), canActivate: [ AdminGuard ], data: { preload: true }, } ];

Add canActivate: [ AdminGuard ] to the routes you want to secure.
This way, you can implement the logic you need for each Guard. In this case, allow access to the CMS module for admin users only.


Contribution created by: Kevin Fiorentino.

Contributions 14

Questions 3

Sort by:

Want to see more contributions, questions and answers from the community?

Bueno ya sabemos que los profesores están despegados de los comentarios de sus alumnos, porque no contestan nada, ni a preguntas ni a nada, que lástima, con lo buena que es esta plataforma …

user.model.ts

export interface User {
  id: string;
  name: string;
  email: string;
  password: string;
  role: 'customer' | 'admin';
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface CreateUserDTO extends Omit<User, 'id' | 'role'> {}

profile.component.html

<div *ngIf="user">
    <h1>My Profile</h1>
    <p>Nombre: {{user.name}}</p>
    <p>Email: {{user.email}}</p>
    <p>Role: {{user.role || 'customer'}}</p>
</div>

esa es una solución fácil y ya veremos cuando apliquen lo del admin

Actualmente la API no permite agregar una propiedad “role” para la creación de nuevos users

Guards

Los Guards en Angular, son de alguna manera: middlewares que se ejecutan antes de cargar una ruta y determinan si se puede cargar dicha ruta o no.

Para no tener problemas con el rol del usuario, si se está continuando el desarrollo desde el curso anterior, se tiene que tener en cuenta que la API ahora es otra.
https://damp-spire-59848.herokuapp.com
La del curso anterior es
https://young-sands-07814.herokuaoo.com/api/iusers

Para generar guardianes es:

ng g g

la segunda g es por Guards, para generar lo que nos enseña en esta clase es

ng g g guards/auth

Todo iba bien, hasta que cambian el api, por que la que se venia desarrollando no soporta los roles

el tema de los guardianes está cool 🖖

Les comparto el código del archivo auth.guard.ts con el que he podido continuar con el curso a la fecha:

import { inject } from '@angular/core';
import { CanActivateFn } from '@angular/router';
import { TokenService } from '../services/token.service';


export const authGuard: CanActivateFn = (route, state) => {
  const tokenService: TokenService = inject(TokenService);
  if (tokenService.getToken()) {
    return true;
  }
  return false;
};

El resto de archivos los tengo igual que los trabajados en la clase.

Si están trabajando con el código anterior y no lo han descargado del repositorio del profesor, como yo eh hecho. Probablemente tengan problemas con el Login. El problema es que como cambiaron de API, el usuario que por default pusieron en el código anterior no existe. Para esto solo tienen que crear un nuevo usuario con el siguiente endpoint:

POST: https://damp-spire-59848.herokuapp.com/api/users

{
    "name": "Usuario",
    "email": "[email protected]",
    "password": "123456"
}

Después poner el la parte del componente “nav.component.ts”, en el método login:

login(): void {

    this.authService.loginAndGet('[email protected]', '123456')
    .subscribe(user => {
      console.log(user);
      this.profile = user;
    });

  }

Para los que tengan problemas con la creación de los guardianes por
utilicen el comando

ng generate guard guards/auth

Hice esto porque en el nav-bar seguía apareciendo el boton al cambiar de pagina

  ngOnInit(): void {
    this.storeService.myCart$.subscribe(products => {
      this.counter = products.length;
    });
    this.getAllCategories();
    const token = this.tokenService.getToken();
       if(token){
        this.authService.getProfile().subscribe(data=>{
          this.profile =data;
        });
       }
  }
```js import { HttpClient } from '@angular/common/http'; import { Inject, Injectable, PLATFORM_ID } from '@angular/core'; import { JwtHelperService } from '@auth0/angular-jwt'; import { loginResponse, user, userLogin, } from 'src/app/models/user.model'; import { catchError, tap } from 'rxjs/operators'; import { BehaviorSubject, Observable, throwError } from 'rxjs'; import { Router } from '@angular/router'; import { StorageService } from './storage.service'; import { ToastService } from './toast.service'; import { isPlatformBrowser } from '@angular/common'; import { environment } from 'src/app/core/constants/environment'; @Injectable({ providedIn: 'root', }) export class AuthService { private isAuthenticatedSubject = new BehaviorSubject<boolean>( this.isAuthenticated() ); isAuthenticated$ = this.isAuthenticatedSubject.asObservable(); constructor( private http: HttpClient, private router: Router, private localStorage: StorageService, private ToastServices: ToastService, @Inject(PLATFORM_ID) private platformId: object ) {} createUser(userData: user) { const url = `${environment.api.baseUrl}${environment.api.users.create}`; this.ToastServices.show( 'Has sido registrado exitosamente', 'success', 3000 ); return this.http.post<user>(url, userData); } loginUser(userData: userLogin): Observable<loginResponse> { const url = `${environment.api.baseUrl}${environment.api.auth.login}`; return this.http.post<loginResponse>(url, userData).pipe( tap((resp) => { console.log('Respuesta del login:', resp); this.localStorage.setItem('access_token', resp.access_token); this.localStorage.setItem('refresh_token', resp.refresh_token); this.isAuthenticatedSubject.next(true); this.ToastServices.show('Has iniciado sesión', 'success', 3000); }), catchError((error) => { this.ToastServices.show('Usario no registrado', 'error', 3000); return throwError(() => error); }) ); } private isTokenValid(token: string): boolean { const helper = new JwtHelperService(); return !helper.isTokenExpired(token); } public isAuthenticated(): boolean { if (isPlatformBrowser(this.platformId)) { const token = this.localStorage.getItem('access_token'); return token ? this.isTokenValid(token) : false; } return false; } logout(): void { this.localStorage.removeItem('access_token'); this.localStorage.removeItem('refresh_token'); this.isAuthenticatedSubject.next(false); this.router.navigate(['/auth/login']); } updateAuthStatus(): void { const isAuthenticated: boolean = this.isAuthenticated(); this.isAuthenticatedSubject.next(isAuthenticated); } } ```
```js import { Injectable } from '@angular/core'; import { Router} from '@angular/router'; import { StorageService } from '../modules/auth/storage.service'; @Injectable({ providedIn: 'root', }) export class AuthGuard { constructor(private localStorage: StorageService, private router: Router) {} canActivate(): boolean { setTimeout(() => { const token = this.localStorage.getItem('access_token'); if (!token) { this.router.navigate(['/auth/login']); } }, 0); return true; } } ```

Model User

export interface User {
  id: string;
  email: string;
  password: string;
  name: string;
  role: string;
}