Artículo
· 25 ago, 2023 Lectura de 4 min

QuinielaML - Usando autenticación JWT

Aprovechando la aplicación de Quiniela ML y como indicamos en el artículo anterior vamos a explicar como podemos realizar una autenticación JWT entre nuestro frontend desarrollado en Angular y nuestro backend desarrollado en InterSystems IRIS.

Os recuerdo como es la arquitectura de nuestro proyecto de QuinielaML:

Habitualmente es un proceso bastante engorroso en las aplicaciones web el desarrollo de la administración y gestión de acceso de los usuarios, pero en nuestro caso InterSystems IRIS nos simplifica el proceso al proporcionarnos toda la infraestructura que necesitamos.

JSON Web Token Authentication

IRIS proporciona a las aplicaciones web que se conecten con la instancia desplegada la posibilidad de realizar la conexión vía JWT de un forma sencilla y directa.

Recordemos cual es el ciclo de vida de una petición de autenticación JWT:

JWT client server authentication flow

En nuestro caso el cliente será nuestra aplicación de frontend desarrollada en Angular y el servidor será nuestra instancia de IRIS.

Como véis el proceso comienza con el envío de la solicitud de logueo desde el cliente al servidor, el servidor validará los datos del usuario generando un token en formato JSON que devolverá a la aplicación cliente. El cliente opcionalmente podrá validar el token recibido y posteriormente lo deberá incluir en la cabecera de sus llamadas al servidor para poder obtener los recursos solicitados.

Como hemos dicho, IRIS facilita la gestión de la autenticación vía JWT y para ello nos proporciona los siguientes endpoints que nuestra aplicación cliente puede utilizar:

  • /login: una llamada a este endpoint mediante autenticación HTTP básica o con credenciales válidas en el cuerpo de la solicitud devuelve un token de acceso y un token de refresco que se pueden usar en solicitudes posteriores.
  • /logout: una llamada a este endpoint, si no utiliza Group-By-ID, invalida el token de acceso proporcionado y el token de refresco asociado. Si utiliza Group-By-ID, todas las sesiones con el Group-By-ID actual se invalidan.
  • /refresh: una llamada a este endpoint emite un nuevo par de tokens de acceso y refresco cuando se invoca con un token de actualización válido. Esto invalida el par de tokens de actualización y acceso anterior.
  • /revoke: si no se utiliza Group-By-ID, esto es funcionalmente lo mismo que /logout. Si se utiliza Group-By-ID, esto revoca solo el par de tokens de refresco y acceso actuales.

Configuración de login desde frontend

Como ya hemos indicado, hemos desarrollado el frontend de nuestra aplicación usando Angular. Desde nuestra página de HTML login.component.html hemos configurado un formulario que acepta el nombre del usuario y su contraseña y desde la clase de TypeScript procedemos a lanzar la invocación desde el componente de servicios que hemos definido.

Aquí podemos ver como invocamos desde login.component.ts la llamada al servicio:

onSubmit(): void {
    const { username, password } = this.form;

    this.authService.login(username, password).subscribe({
      next: data => {
        this.storageService.save(data.access_token)
        this.isLoggedIn = true;
        this.router.navigate(['home']);
      },
      error: err => {
      }
    });
}

Veamos ahora la llamada que lanzamos desde el servicio auth.service.ts a nuestro backend:

login(username: string, password: string): Observable<any> {
    return this.http.post<Response>(
      AUTH_API + 'login',
      {
        "user": username,
        "password": password,
      },
      httpOptions
    )
}

Como podéis ver tenemos definida nuestra llamada al endpoint login del cual recuperaremos la respuesta y almacenaremos el access_token para autenticar posteriormente nuestras llamadas.

El almacenamiento del token que recibimos de respuesta lo realizaremos desde el servicio storage.service.ts:

save(userToken: string): void {
    window.sessionStorage.setItem(USER_KEY, userToken);
}

Con nuestro token almacenado sólo tenemos que interceptar cada solicitud que enviemos a IRIS e introduciremos el token en la cabecera. Para ello definiremos un HttpInterceptor en la clase auth.interceptor.ts

intercept(req: HttpRequest<any>, next: HttpHandler) {
    // Get the auth token from the service.
    const authToken = this.storageService.getToken();

    // Clone the request and replace the original headers with
    // cloned headers, updated with the authorization.
    if (authToken !== ''){
        req = req.clone({
            headers: req.headers.set('Authorization', 'Bearer ' + authToken)
          });
    }
    // send cloned request with header to the next handler.
    return next.handle(req);
}

Configuración de autenticación JWT en IRIS

Para que nuestro IRIS sea capaz de proporcionar estos servicios deberemos configurar apropiadamente nuestra aplicación web y para ello accederemos desde la opción del menú Administración -> Seguridad -> Aplicaciones -> Aplicaciones Web

Una vez dentro de la configuración de la aplicación deberemos marcar el uso de autenticación de JWT y podremos definir el timeout para el token de acceso y el de refresco:

Con esta configuración no necesitaremos nada más para empezar a utilizar dicho modo de autenticación en nuestras aplicaciones web.

Si tenéis alguna pregunta respecto a la configuración o uso de la autenticación JWT no dudéis en dejar un comentario.

En el próximo artículo revisaremos como configuramos nuestro proyecto QuinielaML para realizar el web scraping mediante Embedded Python.

Comentarios (0)1
Inicie sesión o regístrese para continuar