¡Con esto creo que puedo modificar mis propios proyectos y adaptarlos a mis necesidades, buenÃsimo!
Http Basic
Lo que aprenderás para consumir API con Angular
Solicitudes GET
Detalle de producto
Implementando slides
Solicitudes POST
Solicitudes PUT y PATCH
Solicitudes DELETE
Url Parameters / Paginación
Observable vs. Promesa
Reintentar una petición
Buenas prácticas
El problema de CORS
Manejo de ambientes
Manejo de errores
Transformar peticiones
Evitando el callback hell
Auth
Login y manejo de Auth
Manejo de headers
Uso de interceptores
Enviar Token con un interceptor
Creando un contexto a interceptor
Archivos
Descarga de archivos con Http
Subida de archivos con Http
Despedida
Continúa con el Curso de Angular Router y Programación Modular
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Nicolas Molina
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.
Es posible crear un contexto para los interceptores para indicar si queremos que X endpoint sea interceptado o no.
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.
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);
}
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
¡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 ‘add-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 ‘…api/auth/profile’ tiene el contexto ‘{context: addTokenHeader()}’, que resuelve poner el ‘AUTH_TOKEN’ a true para que en el if del interceptor ‘if(request.context.get(AUTH_TOKEN)) {’ solucione adherir el
’headers: request.headers.set(‘Authorization’, 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.
Excelente clase!
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?