JWT
(JSON Web Token) es un estándar qué está dentro del documento RFC 7519.
En el mismo se define un mecanismo para poder propagar entre dos partes, y de forma segura, la identidad de un determinado usuario, además con una serie de claims o privilegios.
Estos privilegios están codificados en objetos de tipo JSON, que se incrustan dentro de del payload o cuerpo de un mensaje que va firmado digitalmente.
Angular Interceptores
Cómo podemos aprovechar esta funcionalidad que nos da Angular para modificar las peticiones. No debe confundirse con los Guards. Los interceptors modifican las peticiones (enpoints, servicios) y los guards controlan las rutas de navegación entre páginas de la aplicación web, permitiendo o denegando el acceso por ejemplo.
Para crear nuestro interceptor, tenemos que generar un servicio usando el CLI de angular.
ng g interceptor JwtInterceptor
Una vez hecho todo eso implementaremos la parte en que nuestro interceptor agrega la cabecera ‘Authorization’ con el token que vayamos a usar, como modo de ejemplo, imaginemos que tenemos el token almacenado en cookie con la clave ‘token’ y para obtener el token tendremos que hacer lo siguiente:
const token: string = this.cookieService.get('token');
ahora declaramos una constante que guarde el token obteniéndolo del cookie .
El token puede o no existir en nuestro cookie, y para no estar enviando la cabecera ‘Authorization’ vacía, condicionamos si existe algún token, posteriormente si existe un token, modificamos el request agregándole la cabecera, utilizando el método clone que viene en nuestro request de tipo HttpRequest y pasándole la cabecera con el token. una vez modificado el request lo retornamos de nuestro método.
Ahora bien, hay que recordar que los interceptors se ejecutan en cada petición que se realiza al servidor, siempre y cuando sean registrados. Para registrar un interceptor se tiene que proveer en el array de providers: [] en nuestro módulo raíz, por lo general AppModule. Importamos HTTP_INTERCEPTORS y HttpClientModule, luego proveémos nuestro interceptor. El módulo quedaría así:
Podemos observar que en nuestro provider utiliza la propiedad multi: true, esto permitirá agregar más interceptors si lo requerímos y no sobre escribir nuestro interceptor. En otras palabras, crean un array con el mismo provider token (HTTP_INTERCEPTORS). En este punto, nuestro interceptor modificará cada petición que se haga al servidor siempre y cuando exista un token.
Otra cosa que podríamos realizar en nuestro interceptor sería redirigir al usuario a la página de login cuando el token haya expirado o no tenga un token válido por ejemplo.
Modificaremos nuestro interceptor un poco, importando el operador catchError de rxjs, que recibe un método que va a revisar el status de la respuesta que el servidor nos devuelve. Cuando detectemos que el status es 401, hacemos la redirección a la vista de login, de igual manera el servicio Router e injectarlo en el constructor para utilizarlo y hacer la redirección.
Nota: En este método podemos aprovechar a manipular los errores para devolverlos a los servicios de una manera más limpia, pero eso sería otro tema.
Nuestro interceptor ahora quedaría de la siguiente manera:
En el método catchError se tiene que devolver el error y para eso usamos throwError.
Conclusión
Los interceptors son una manera sencilla de manipular nuestras peticiones y respuestas, evitando así realizar dicha modificación en cada servicio que realizamos manualmente. Esto nos ayuda a tener un código más limpio y mantenible.