Avanzado #2 Autenticación básica Angular.io con Auth0 🔒
Cuando creamos una aplicación una de las partes más importantes es la autenticación dado que deseamos que sea segura y podamos proteger los datos de los usuarios, aprendamos juntos como hacerlo 🔐
En este desafío vamos a aprender a tener una autenticación con Auth0 y las ventajas de usarla.
En un mundo donde casi tod@s usan la misma contraseña para todo, la fecha de su cumpleaños, el nombre de su mascota, entre otras malas prácticas para protección de datos, te estás asegurando de cuidar la información de manera simple. 🔐
Esta cuenta es totalmente gratuita, Auth0 se encargará de la autenticación de los usuarios por nosotros, ellos tienen unos servicios, llamados API donde tú los llamas y según la información que le envíes él te responderá si es el usuario correcto, también nos realizará procesos de autenticación de terceros como Google o recordar contraseña, se asegurará que no sea un correo maligno que le este haciendo peticiones cuando intenta recordar la contraseña y que no están tratando de atacar tu aplicación, asiendo así, un inicio de sesión muy seguro.
Entra a https://auth0.com/, y crearas una cuenta así:
Podrás crear una cuenta con un usuario y contraseña o con una cuenta que ya tengas anteriormente por un tercero.
Yo usaré la de Google para este ejemplo.
Cuando ya ingreses a tu cuenta, podrás ver una plataforma de manejo de tus aplicaciones e inicios de sesión en ella, puedes sacar estadísticas, hacer grupos por roles y permisos, decir a que usuario les va a otorgar ciertos accesos y a cuales no. ¡Y mucho más!
Al darle click en + Create Application creamos una nueva instancia para manejar el inicio de sesión de nuestra aplicación.
Y seleccionamos Single Page Web Application como el tipo de autenticación que vamos a usar.
Curando ya tengamos nuestra nueva instancia, Auth0 nos va a proveer de un client ID que usaremos para todos los llamados a su API.
Vamos a tomar la URL de nuestra aplicación que nos genera https://stackblitz.com/ y vamos a usarla para que Auth0 sepa que cuando hagamos un llamado a su API desde nuestra aplicación, nos responda con la configuración que esperamos al respecto.
Esta es la ubicación de la URL de nuestra aplicación en https://stackblitz.com/
Guarda los cambios y estas listo para usarla.
Paso 3: Vamos insertar la funcionalidad para hacer llamados a funcionalidades externas como una API y adicionaremos router.
Ya aprendiste como adicionar router, ahora vamos a adicionar la funcionalidad HTTP Client Module en nuestro app.module.ts y luego hacemos su llamado a desde imports
En este archivo vamos a sacar las variables necesarias para manejar nuestra aplicación, esta va a ser la información que le entregaremos a la API de Auth0 y con ella nos identificaremos.
vamos a crear un archivo llamado donde las pondremos auth0-variables.ts
No olvides, que cuando termines el ejercicio debes borrar esas variables, para que personas en internet no usen tu cuenta sin tu autorización o roben tu información.
Paso 5: Crea un servicio de autenticación
La mejor manera de administrar y coordinar las tareas necesarias para la autenticación del usuario es crear un servicio reutilizable. Con el servicio en su lugar, podrá llamar a sus métodos a través de su aplicación. Se puede crear una instancia del objeto WebAuth de auth0.js en el servicio AuthService.ts.
AuthService.ts
import { Injectable } from"@angular/core";import*as auth0 from"auth0-js";import { environment } from"../../environments/environment";import { Router } from"@angular/router";(window asany).global = window;@Injectable()exportclassAuthService { auth0 =newauth0.WebAuth({// the following three lines MUST be updated domain:environment.domain,// TODO '<YOUR_AUTH0_DOMAIN>' audience:environment.audience,// TODO: https://<YOUR_AUTH0_DOMAIN>/userinfo clientID:environment.clientID,// TODO: '<YOUR_AUTH0_CLIENT_ID>' redirectUri:environment.redirectUri, responseType:"token", scope:"openid profile" });// Store authentication data expiresAt:number; userProfile:any; accessToken:string; authenticated:boolean;constructor(private router:Router) {this.getAccessToken(); }login() {// Auth0 authorize requestthis.auth0.authorize(); }handleLoginCallback() {// When Auth0 hash parsed, get profilethis.auth0.parseHash((err, authResult) => {if (authResult &&authResult.accessToken) {window.location.hash ='';this.getUserInfo(authResult); } elseif (err) {console.error(`Error: ${err.error}`); }this.router.navigate(['/']); }); }getAccessToken() {this.auth0.checkSession({}, (err, authResult) => {if (authResult &&authResult.accessToken) {this.getUserInfo(authResult); } }); }getUserInfo(authResult) {// Use access token to retrieve user's profile and set sessionthis.auth0.client.userInfo(authResult.accessToken, (err, profile) => {if (profile) {this._setSession(authResult, profile); } }); }private_setSession(authResult, profile) {// Save authentication data and update login status subjectthis.expiresAt =authResult.expiresIn *1000+Date.now();this.accessToken =authResult.accessToken;this.userProfile = profile;this.authenticated =true; }logout() {// Log out of Auth0 session// Ensure that returnTo URL is specified in Auth0// Application settings for Allowed Logout URLsthis.auth0.logout({ returnTo:'http://localhost:4200', clientID:environment.auth.clientID }); }getisLoggedIn():boolean {// Check if current date is before token// expiration and user is signed in locallyreturn (Date.now() <this.expiresAt) &&this.authenticated; }}
Por si tienes alguna duda. Aquí te explicamos cómo funciona: 👷♀️
1. En auth0.WebAuth( estamos asignando las variables de configuración que creamos en el paso anterior.
2. El servicio incluye varios métodos para manejar la autenticación. login: las llamadas autorizan desde auth0.js que inicia el inicio de sesión universal.
handleAuthentication: busca un resultado de autenticación en el hash de URL y lo procesa con el método parseHash de auth0.js.
setSession: establece el token de acceso del usuario, el token de identificación y la hora en que caducará el token de acceso cerrar sesión: elimina los tokens del usuario del almacenamiento del navegador.
isAuthenticated: verifica sí el tiempo de vencimiento del token de acceso ha pasado.
Paso 6: Crea una clase que nos manejará el callback
Para manejar la ruta de devolución de llamada (https://angular-basic-with-auth0.stackblitz.io/callback), vamos a definir un componente que se encargará solo de esto, crea un nuevo archivo llamado callback.component.ts dentro del directorio app e inserta el siguiente código:
Paso 7: Vamos a crear el routing model de nuestra aplicación
Para manejar la ruta de desde nuestra a aplicación al inicio de sesión universal solo necesitamos crear un app-routing.module.ts que nos controlará cada vez que vayamos a autenticarnos y volvamos a nuestra aplicación:
Paso 9: Vamos a poner el login en la interfaz de nuestra aplicación
Usaremos la siguiente lógica para llamar al método de autenticación y así determinar si debemos mostrar un elemento de IU específico o no. Como ejemplo, solo queremos mostrar el enlace de Log In si no está autenticado, y Log Out si no está autenticado.
En el archivo app.component.html pondremos lo siguiente:
Nos daremos cuenta que el mismo stackblitz se da cuenta que nos hace falta instalar un paquete y nos pide que instalemos el de Auth0.js y damos clic en install package