No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Compra acceso a todo Platzi por 1 a帽o

Antes: $249

Currency
$209/a帽o

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscr铆bete

Termina en:

15D
13H
43M
21S

Creando un contexto a interceptor

20/23
Recursos

Suele ocurrir que un front-end consume m谩s de un backend diferente, con diferentes URLs, que eventualmente podr铆an utilizar diferentes tokens o necesitar cada uno de una manipulaci贸n diferente de la request por parte del interceptor.

Manipulando m煤ltiples tipos de solicitudes

Es posible crear un contexto para los interceptores para indicar si queremos que X endpoint sea interceptado o no.

1. Importando clases necesarias

Para esto, importando HttpContextToken y HttpContext desde @angular/common/http vamos a crear una funci贸n para validar si el endpoint necesita o no la inyecci贸n de un token.

// interceptors/token-interceptor.interceptor.ts
import { HttpContextToken, HttpContext } from '@angular/common/http';

const ADD_TOKEN = new HttpContextToken<boolean>(() => true);

export function addToken() {
  return new HttpContext().set(ADD_TOKEN, false);
}

Creamos la constante ADD_TOKEN que indicar谩 si el endpoint necesita de un token o no. Por defecto, todos los endpoints necesitan un token. La funci贸n addToken() har谩 que no se inyecte el token cuando no se requiere.
Tambi茅n puedes utilizar la l贸gica inversa, que ning煤n endpoint por defecto utilice el token y solo habilitar manualmente los que si lo requieren.

2. Creando el contexto para las solicitudes

En la l贸gica del interceptor, colocamos un IF para validar si la petici贸n necesita o no del token.

// interceptors/token-interceptor.interceptor.ts
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<unknown>> {
  if (request.context.get(ADD_TOKEN)) {
    request = this.addHeaders(request);
    return next.handle(request);
  } else
    return next.handle(request);
}

3. Denegar la utilizaci贸n del token

Ahora, importamos dicha funci贸n y la utilizamos para que un endpoint no requiera del token.

// services/auth.service.ts
import { addToken } from '../interceptors/token-interceptor.interceptor';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  constructor(private http: HttpClient) { }

  loginUser(credentials: Credentials): Observable<Login> {
    return this.http.post<Login>(`https://example.com/api/login`, credentials, { context: addToken() });
  }
}

Agregamos como argumento context a las opciones de la solicitud. El endpoint de Login no suele necesitar de un token para funcionar, es el 煤nico que excluimos del uso del interceptor.


Contribuci贸n creada por: Kevin Fiorentino.

Aportes 7

Preguntas 4

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

隆Con esto creo que puedo modificar mis propios proyectos y adaptarlos a mis necesidades, buen铆simo!

El tema del contexto y los interceptores is crazy!

Como as铆, me confunde el profesor en el minuto 2:59. En la clase anterior se supone que el interceptor va a estar a la escucha de cualquier petici贸n sino se le agrega un contexto pero en ese minuto de esta clase dice todo lo contrario, que al no enviar ning煤n contexto no todas van a estar siendo evaluadas por el interceptor. No se supone que al poner contexto en una petici贸n es para que el interceptor este al pendiente de solo esa petici贸n y no de todas las dem谩s peticiones?..O entend铆 mal?. No se si alguien me pueda explicar esta parte

Tenia conocimiento de los interceptors, pero estas ultimas 2 clases me volaron la cabeza.

Sin duda la mejor forma de aprender es aprendiendo a desaprender.

Vale siguiendo, la misma f贸rmula de interceptores para aquellas rutas que deban agregar un token de autenticaci贸n, por ejemplo, el endpoint donde solicitamos el profile del usuario logueado, he realizado lo siguiente, para no estar metiendo el token en todas las peticiones:

in 鈥榓dd-token.interceptor.ts鈥

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpContext,
  HttpContextToken
} from '@angular/common/http';
import { Observable } from 'rxjs';

import { TokenService } from '../services/token.service';

const AUTH_TOKEN = new HttpContextToken<boolean>(()=> false);

export function addTokenHeader() {
  return new HttpContext().set(AUTH_TOKEN, true);
}

@Injectable()
export class AddTokenInterceptor implements HttpInterceptor {

  constructor(
    private tokenService: TokenService
  ) {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    request = this.addToken(request);
    return next.handle(request);
  }

  // this.http.get|post|put|delete(<CUALQUIER URL>, {context: addTokenHeader()})
  private addToken(request: HttpRequest<unknown>) {
    if(request.context.get(AUTH_TOKEN)) {
      const token = this.tokenService.getToken();
      if(token) {
        const authRequest = request.clone({
          headers: request.headers.set('Authorization', `Bearer ${token}`)
        });
        return authRequest;
      }
    }
    return request;
  }
}

in auth.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { switchMap, tap } from 'rxjs/operators';

import { Auth } from '../models/auth.model';
import { User } from '../models/user.model';
import { TokenService } from './token.service';
import { addTokenHeader } from '../interceptors/add-token.interceptor';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private apiUrl = 'https://young-sands-07814.herokuapp.com';

  constructor(
    private http: HttpClient,
    private tokenService: TokenService
  ) { }
  login(email: string, password: string) {
    return this.http.post<Auth>(`${this.apiUrl}/api/auth/login`, {email, password})
    .pipe(
      tap(response => this.tokenService.saveToken(response.access_token))
    );
  }
  getProfile() { // el interceptor se encarga de a帽adir el token
    return this.http.get<User>(`${this.apiUrl}/api/auth/profile`, {context: addTokenHeader()});
  }
  loginAndGetProfile(email: string, password: string) {
    return this.login(email, password)
    .pipe(
      switchMap(() => this.getProfile())
    )
  }
}

Ahora la petici贸n 鈥樷pi/auth/profile鈥 tiene el contexto 鈥榹context: addTokenHeader()}鈥, que resuelve poner el 鈥楢UTH_TOKEN鈥 a true para que en el if del interceptor 鈥榠f(request.context.get(AUTH_TOKEN)) {鈥 solucione adherir el
鈥檋eaders: request.headers.set(鈥楢uthorization鈥, Bearer ${token})鈥 y con ello pasar la l贸gica del servidor para endpoints con autorizaci贸n y s贸lo para aquellos endpoints donde se necesite.

Tenga en cuenta esta clase de Backend Pr谩ctico <https://platzi.com/new-home/clases/2164-practico-backend/34222-diseno-de-un-servicio-que-integre-autenticacion/>

Excelente clase!