El curso de Express. js - módulo 9: autenticación y autorización | Shivendra Raghuvanshi | Skillshare

Velocidad de reproducción


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

El curso de Express. js - módulo 9: autenticación y autorización

teacher avatar Shivendra Raghuvanshi, Lead Developer and Online Teacher

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Introducción

      2:38

    • 2.

      Autenticación y autorización: una introducción

      4:41

    • 3.

      Crea el modelo de usuario

      4:04

    • 4.

      Registro de usuarios

      8:33

    • 5.

      Uso de Lodash

      6:03

    • 6.

      Cómo usar hash de contraseñas

      8:23

    • 7.

      Autenticación de usuarios

      5:20

    • 8.

      Prueba de la autenticación

      2:48

    • 9.

      Tokens web JSON

      5:58

    • 10.

      Generación de tokens de autenticación

      4:36

    • 11.

      Almacenamiento de secretos en variables de entorno

      7:25

    • 12.

      Establecer encabezados de respuesta

      4:30

    • 13.

      Encapsulación de lógica en modelos de manguesa

      8:17

    • 14.

      Middleware de autorización

      8:44

    • 15.

      Protección de rutas

      3:50

    • 16.

      Conoce al usuario actual

      4:50

    • 17.

      Cerrar sesión de usuarios

      2:30

    • 18.

      Autorización basada en roles

      6:59

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

3

Estudiantes

--

Proyecto

Acerca de esta clase

El módulo 9: autenticación y autorización se centra en los conceptos esenciales de autenticación y autorización en las aplicaciones web modernas. Aprenderás a implementar medidas de seguridad robustas para proteger tus API y gestionar los roles de usuario de manera efectiva. Desde el registro de usuarios hasta la generación y verificación de tokens web JSON (JWT), este módulo te equipa con todo lo que necesitas para proteger tus aplicaciones de backend.

Lo que aprenderás

  • Crea un modelo de usuario con capacidades de autenticación.
  • Implemente el registro seguro de usuarios con contraseñas en hash.
  • Autentifica a los usuarios con la autenticación basada en JWT.
  • Protege rutas sensibles con autorización y middleware basados en roles.
  • Utiliza variables de entorno para el almacenamiento seguro de secretos.
  • Administra sesiones de usuario, cierres de sesión y niveles de acceso para diferentes roles.

Conoce a tu profesor(a)

Teacher Profile Image

Shivendra Raghuvanshi

Lead Developer and Online Teacher

Profesor(a)
Level: Intermediate

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

Transcripciones

1. Introducción: Bienvenido de nuevo al curso Express Jazz, Modelo nueve, autenticación y autorización. Mi nombre es ShenraRunhi, y seré tu instructor para este A lo largo de los años, he tenido el privilegio de crear sistemas backend seguros y escalables para una variedad de aplicaciones, y estoy aquí para compartir mi experiencia con usted Uno de mis mejores proyectos consistió en diseñar un sistema de autenticación de usuarios para una plataforma de comercio electrónico, lo que mejoró significativamente su seguridad y usabilidad. Hoy, aprenderás a construir algo igual de impactante. En este módulo, estamos profundizando en la autenticación y autorización, dos aspectos críticos del desarrollo web moderno. Así aprenderás a registrar usuarios de forma segura usando contraseñas hash, autenticar usuarios con webtkens JCN, proteger rutas sensibles con middleware y, finalmente, implementar la autorización basada en roles para administrar los permisos usuarios de forma segura usando contraseñas hash, autenticar usuarios con webtkens JCN, proteger rutas sensibles con middleware y, finalmente, implementar la autorización basada en roles para administrar los permisos de usuario. Este conocimiento es crucial para asegurar cualquier aplicación backend, y al final de este módulo, tendrá confianza en implementar estas características en sus proyectos Por lo que este módulo está diseñado para Bg en desarrolladores que quieran llevar sus aplicaciones Express JS al siguiente nivel. Si has completado los módulos anteriores, ya estás listo para comenzar. conocimientos básicos de JavaScript, recomiendan conocimientos básicos de JavaScript, no JS, y Monger DB La autenticación y autorización son las piedras angulares de cualquier aplicación web segura Al dominar estos conceptos, no solo construirás aplicaciones más seguras, sino que también aumentarás tu valor como desarrollador Estos deben tener habilidades para crear plataformas centradas en el usuario en el mundo tecnológico actual. Y por último, para el proyecto, integrarás todo lo que hayas aprendido en la app Fair Wheels. Entonces, más específicamente, implementará funcionalidad de registro de usuarios e inicio de sesión, autenticará de forma segura a los usuarios usando tokens web JCN Aplicar autorización basada en roles para proteger rutas y recursos. Al final, tendrás un sistema de gestión de usuarios seguro y escalable para la app Fair Wheels. Este módulo es un cambio de juego para tu viaje de desarrollo de Bend Así que construyamos aplicaciones seguras juntas. Te veré en la primera conferencia. Empecemos. 2. Autenticación y autorización: una introducción: Bien, así que volvamos a nuestra aplicación Fair Wheels. Hasta ahora, hemos construido estos endpoints de API. Así podemos administrar empresas, autos, clientes y alquileres. Ahora, casi todas las aplicaciones que existen requieren algún tipo de autenticación y autorización. Entonces en esta sección, vamos a llevar esta aplicación al siguiente nivel e implementar la autenticación y autorización. Entonces, antes de ir más lejos, quiero asegurarme de que estamos en la misma página. Por lo que la autenticación es el proceso de identificar si el usuario es quien afirma ser. Ahí es cuando iniciamos sesión. Por lo que enviamos nuestro usuario y contraseña al servidor, y el servidor nos autentica La autorización es determinar si el usuario tiene el permiso adecuado para realizar la operación dada. Entonces, en nuestra aplicación Fair Wheels, queremos asegurarnos de que solo los usuarios autenticados o solo los usuarios que hayan iniciado sesión puedan realizar operaciones que modifiquen los datos Entonces, si el usuario es anónimo, si no está conectado, solo puede leer datos de estos endpoints Si quieren crear una nueva compañía o actualizar un auto, primero tienen que ser autenticados Ahora como seguridad adicional, queremos asegurarnos de que solo los usuarios administradores puedan eliminar datos. Entonces ese es un segundo nivel de autorización. Estamos hablando de permisos aquí. Entonces estos son los requisitos que vamos a implementar en esta sección. Entonces, para hacer esto, necesitamos agregar dos nuevos endpoints a nuestra aplicación Primero, deberíamos poder registrar usuarios. Para eso, vamos a enviar una solicitud de post para que se corte API slash USUARIOS porque publicamos, creamos nuevos recursos En este caso, un nuevo usuario. También deberíamos poder iniciar sesión en un usuario, y eso se usa para la autenticación. Ahora, aquí tienes una pregunta para ti. ¿Qué método SDDP debemos usar para implementar el inicio de sesión? Porque con login, no estamos creando un nuevo recurso. No estamos actualizando ni eliminando uno existente. Entonces, ¿cómo podemos implementar esto en términos de descanso? Este es uno de esos escenarios que puedes encontrar frecuentemente en aplicaciones del mundo real. A veces la operación con la que estás tratando no tiene esa creación, lectura, actualización, eliminación semántica La forma en que modelizamos esto en términos de descanso es refiriéndonos a esto como petición o comando Entonces estás creando una nueva solicitud de inicio de sesión o un comando de inicio de sesión. En ese caso, usaremos post porque estamos creando un nuevo recurso, así que barra barra API slash Logins Ahora en tu aplicación, tal vez quieras almacenar todos los inicios de sesión en la aplicación en una colección separada en Mongo Así que puedes ver que usar post tiene mucho sentido aquí. Pero incluso si no almacenas inicios de sesión individuales y solo quieres validar el usuario y la contraseña, aún puedes tratar este recurso como recurso sesión y usar post para crearlo Ahora, aquí tienes un ejercicio para ti. Quiero que implemente esta API para registrar nuevos usuarios. Entonces para cada usuario, queremos tener estas propiedades, nombre, correo electrónico y contraseña. Además, al definir su esquema para la propiedad email en el objeto de tipo de esquema, establezca la propiedad unique en true. Entonces, cuando definimos el esquema, establecemos el tipo de correo electrónico a un objeto que es nuestro objeto de tipo de esquema. Establecimos el tipo aquí en string y también establecemos unique a true. Entonces con esto, nos aseguramos de que no almacenaremos dos documentos con el mismo correo electrónico en Mongo Di B. Bien. Así que adelante e implementa solo esta API para registrar nuevos usuarios. Yo voy a hacer lo mismo en la próxima conferencia. 3. Crea el modelo de usuario: Todo bien. Entonces primero, voy a definir un nuevo modelo de usuario. Así que aquí en la carpeta de modelos en un nuevo archivo usuario punto js. Ahora para ahorrar tiempo, voy a ir a la compañía punto js y pedirme prestado un código de aquí Así que copia de nuevo touserdtjs, pegarlo aquí. Ahora en la parte superior, así tenemos este esquema. Voy a definir esto mientras llamo al método modelo. Realmente no hay necesidad en este caso de definir esto como una constante separada. Entonces vamos a obtener este objeto de esquema y agregarlo aquí. Y ahora podemos deshacernos de este esquema. Bien, eso es mejor. Entonces ese es nuestro modelo. Deberíamos llamar a este usuario constante. Y la colección correspondiente también deben ser usuarios. Ahora aquí, tenemos la propiedad name, que es una cadena. Se requiere, y es de 5 a 50 caracteres. Eso me suena bien. A continuación, agreguemos el correo electrónico. Entonces voy a agarrar todo esto bueno, duplicarlo. Y la segunda propiedad es el correo electrónico. Entonces nuevamente, tenemos estas propiedades. Me gustaría aumentar la longitud máxima a 255 caracteres. Y además, como te dije en la última conferencia, deberíamos agregar la propiedad única para asegurarnos de que no almacenamos dos usuarios con el mismo correo electrónico en Manga Divi Y la última propiedad es Passwb. Entonces voy a copiar todo esto, duplicar y agregar esta propiedad de contraseña. Ahora voy a establecer la longitud máxima de las contraseñas a un valor mayor porque vamos a hash estas contraseñas. Y aquí no necesitamos la propiedad única. Siguiente es nuestra función de validar. Entonces necesitamos renombrar esto para validar usuario. Validar usuario que toma un parámetro de usuario. Aquí tenemos nombre que es 5 a 50 caracteres, y es obligatorio. Tenemos correo electrónico, que debe tener 5-255 caracteres. Debe ser requerido. Y aquí también llamamos al método de correo electrónico para asegurarnos de que es un correo válido. Y por último, tenemos contraseña, que también es una cadena con mínimo cinco caracteres y máximo, digamos, 255 según sea necesario. Entonces esta es la contraseña que el usuario envía en texto plano. Vamos a hash esto, que va a ser una cadena más larga, y esa es la cuerda que almacenaremos en Mongo TV Así que terminamos con nuestra función de usuario válida. Ahora necesitamos exportar nuestro modelo de usuario, así que no necesitamos la primera declaración de exportación que sea para nuestro esquema delete. Aquí vamos a exportar esto como usuario, y nuestra función de validar también es buena. Hermoso. Así que terminamos con nuestro modelo de usuario. En la próxima conferencia, voy a agregar una ruta para registrar nuevos usuarios. 4. Registro de usuarios: Bien. Ahora vamos a crear una nueva ruta para registrar nuevos usuarios. Entonces aquí en la carpeta rutas, voy a agregar un nuevo archivo usuarios punto js. Ahora, una vez más, para ahorrar tiempo, voy a ir a las empresas punto js y copiar estas declaraciones requeridas así como la segunda ruta en nuestro nuevo módulo. Entonces copia, pégalo aquí. Nuevamente, copia la ruta del poste. Y pega aquí. Y por cierto, sólo estoy haciendo esto porque no quiero perder tu tiempo viéndome escribir todo esto a mano. En el mundo real, debes evitar enfoque de copiar y pegar a menos que seas muy cuidadoso y vayas a leer cada línea del código copiado para asegurarte de que no cometiste un error. Siempre es mejor escribir el código a mano. Ahora, hagamos cambios. Entonces, en la parte superior, necesitamos importar el modelo de usuario en lugar de la compañía. Entonces a partir de modelos user, importamos la clase user, así como la función validate. También necesitamos Express y Router. Así que aquí está nuestra nueva ruta que se plantea para crear nuevos usuarios. Y por último, necesitamos exportar este router. Así módulo dot Exportaciones. Ponemos esto a este router. Ahora, tenemos que volver a nuestro punto índice JS y decirle a Express que para cualquier ruta que comience con slash ABS SRS, deberíamos usar este router que estamos exportando aquí Entonces vamos a Index o Js. En la parte superior, vamos a importar este nuevo módulo. Usuarios tan constantes. Establecemos esto para requerir de los usuarios de la carpeta rutas. Y entonces aquí llamamos app que dan a nuestro path slash APAs Usuarios y nuestro Router, es decir usuarios Bien, entonces hemos construido el panorama general. Ahora, volvamos a nuestro módulo de usuarios e implementemos esta nueva ruta. Entonces aquí vamos a validar la solicitud. Si no es válido, vamos a devolver un error 400, que es mala solicitud. De lo contrario, vamos a crear un nuevo objeto de usuario y guardarlo en la base de datos. Entonces vamos a mantener las dos primeras líneas exactamente como están. Queremos validar la solicitud. Estamos utilizando nuestra función Joy validate. Entonces, si las propiedades de nombre, correo electrónico o contraseña no son válidas, vamos a devolver un error 400 al cliente. Ahora, a continuación, tenemos que hacer otro tipo de validación. Quieres asegurarte de que este usuario no esté ya registrado. Entonces llamamos usuario punto Fine one, pasar un objeto de consulta aquí. Estamos buscando usuario con un email dado que se solicite dot body dot email. Así que tenga en cuenta que aquí, no usé bien por ID porque no estamos buscando al usuario por su ID. Los estamos buscando por una de sus propiedades. Tan fino uno. Ahora esto devuelve una promesa. Entonces lo esperamos y obtenemos un objeto de usuario. Ahora bien, en este caso, estoy definiendo una variable en lugar de una constante porque vamos a restablecerla como verás en un segundo. Entonces en este caso, si tenemos este objeto de usuario en la base de datos, debemos devolver un error de solicitud incorrecta al cliente. Así que devuelve el estado del punto de respuesta 400, que es mala solicitud punto ENVIAR y aquí está el mensaje usuario ya registrado. Entonces en este punto, tenemos un objeto de usuario válido. Este usuario no está registrado en la base de datos, por lo que necesitamos guardar este usuario en la base de datos. Entonces aquí, voy a restablecer este objeto de usuario porque en este punto, debería ser no. Establecemos esto a un nuevo usuario, y aquí establecemos las propiedades. Entonces nombre establecemos esto para solicitar cuerpo de punto, nombre de punto. Correo electrónico para solicitar dot body dot email. Y contraseña para solicitar contraseña del cuerpo del punto. Entonces este es nuestro objeto de usuario. Ahora lo guardamos. Así que espera, usuario punto guardar, y finalmente, devolver esto al cliente. Entonces no necesitamos estas dos líneas para trabajar con la empresa. Eliminar. Y por último, devolver este nuevo usuario al cliente. Ahora, vamos a probar esto. Así que de vuelta en Cartero, voy a enviar una solicitud de correo a Local Host port 3,000 slash APAS Y luego en el cuerpo de la solicitud, voy a establecer esto en Raw y establecer el tipo en JSON. Aquí pasamos como objeto JSON con tres propiedades, name, Shiv, luego configuramos email Voy a establecer un correo electrónico no válido, y tampoco voy a establecer la contraseña. Quiero asegurarme de que nuestra función de validación funcione correctamente. Así que envía. Bien, tenemos un mal pedido. Eso es bueno. La longitud del nombre debe tener al menos cinco caracteres. Así que déjame cambiar esto a hewnder Bien. Ahora vamos a enviar otra solicitud. Tenemos otra mala solicitud. La longitud del correo electrónico debe tener al menos cinco caracteres. Entonces cambiemos esto a 12, tres, cuatro, cinco, seis, pero este no es un correo válido. Entonces ahora deberíamos obtener un error diferente. El correo electrónico debe ser un correo electrónico válido. Hermoso. Entonces cambiemos esto para probar 123 en regmil.com Et envía otra solicitud. Bien, ahora obtenemos contraseña se requiere. Hermoso. Por último, agreguemos una contraseña que tenga al menos cinco caracteres de largo. Entonces uno, dos, tres, cuatro, cinco, Send. Esta vez obtuvimos una respuesta de 200. Hermoso. Y este es el objeto de usuario que almacenaste en la base de datos. Por lo que tienes la propiedad de identificación así como nombre, correo electrónico y contraseña. Ahora, al registrar un nuevo usuario, no queremos devolver su contraseña al cliente. Entonces eso es algo que vamos a arreglar en la próxima conferencia. Pero enviemos otra solicitud con exactamente los mismos valores. Esta vez, deberíamos obtener un error diferente, diciéndonos que el usuario ya está registrado. Así que envía. Bien, tenemos otra mala petición, y aquí está el mensaje. Usuario ya registrado. Hermoso. Entonces en la próxima conferencia, vamos a modificar la respuesta de esta API y punto. 5. Uso de Lodash: Así que de vuelta en nuestro método post, queremos modificar la respuesta al cliente. Entonces aquí hay dos opciones. Un enfoque es devolver un objeto personalizado como este, establecer el nombre en nombre de punto de usuario y correo electrónico a correo electrónico de punto de usuario. Así que de esta manera, podemos excluir la contraseña y las propiedades de la versión. Este enfoque está perfectamente bien, pero en esta conferencia, voy a presentarte una biblioteca útil que te brinda muchas funciones de utilidad para trabajar con objetos. Si eres un desarrollador experimentado de JavaScript, probablemente sabrás de lo que estoy hablando. Esa es Lourdes. Así que dirígete a lodash.com. Esto es lodash, que es básicamente la versión optimizada del guión bajo El subrayado ha existido desde hace mucho tiempo. Tiene una gran cantidad de motores de utilidad para trabajar con objetos, cadenas, matrices, y así sucesivamente. Entonces, si nos fijamos en la documentación, aquí podemos ver todas las funciones de utilidad que tenemos para trabajar con varios tipos. Tenemos muchas funciones de utilidad para trabajar con matrices, números, cadenas, objetos, etc. Entonces lodash es extremadamente poderoso. Y en esta conferencia, te voy a mostrar cómo usarlo en tu aplicación de nodo. Así que de vuelta en la terminal, NPM instala lodash. Así que tenga en cuenta que la versión actual estoy usando 4.17 0.21. Todo bien ahora de vuelta en el código. Entonces aquí en nuestro modelo de usuario en la parte superior, voy a importar Lodash Por lo que requieren Lodash. Ahora por convención, almacenamos el resultado en una constante llamada guión bajo esto se le puede llamar cualquier cosa, se puede llamar a esto Lodash, pero por convención, usamos subrayado porque eso es corto y limpio Ahora bien, este objeto de subrayado que tenemos aquí tiene un método de utilidad llamado pick so underscore dot Le damos un objeto a esto. En este caso, nuestro objeto de usuario, y luego pasar una matriz de propiedades en este objeto de usuario que queremos elegir. Y esto devolverá un nuevo objeto con solo esas propiedades. Así que aquí en esta matriz, voy a pasar nombre y correo electrónico. Entonces, cuando llamamos a este método pick, obtendremos un nuevo objeto con estas dos propiedades, name y email. Ahora en lugar de repetir manualmente el punto de usuario, podemos usar este método Pi. Eso es más elegante. Entonces podemos reemplazar este objeto aquí con lo que obtenemos del método PI. Tan simple como eso. Ahora, quizás aquí, es posible que desee incluir también la propiedad IR. Entonces así es como usamos el método PIC. De igual manera, podemos modificar este código, y en lugar de repetir solicitar punto cuerpo punto, solicitar punto cuerpo punto, solicitar punto cuerpo punto con guión bajo punto PIC Entonces voy a reemplazar este objeto con guión bajo punto cerdo Le dimos solicitud punto py. Ahora aquí, podríamos tener 50 propiedades. Un usuario malintencionado puede enviarnos propiedades para ser almacenadas en la base de datos. Sólo queremos escoger a mano algunos de estos. Entonces pasamos una matriz. Solo nos interesa el nombre, el correo electrónico y la contraseña. Bien, entonces creamos el usuario y lo guardamos y luego devolvemos este objeto personalizado al cliente. Probemos esto una vez más para asegurarnos de que todo está funcionando. Entonces terminal backend. Ejecutemos la aplicación. Hermoso. Ahora de vuelta en el Cartero Voy a enviar una nueva solicitud a través del servidor. Enviar. Bien, aquí está nuestro nuevo objeto de usuario. Solo tenemos identificación, nombre y correo electrónico. Ahora en todas estas solicitudes hasta el momento, he enviado contraseñas realmente simples. Si quieres hacer cumplir la complejidad de la contraseña, hay un paquete NPM construido sobre Joy llamado Joi password Complexity Joy llamado Joi password Así que de vuelta en Google busca Joy contraseña Complejidad. Ese es el paquete NPM. Entonces con esto, puedes configurar un objeto que determine la complejidad de la contraseña en tu aplicación. Número mínimo de caracteres, máximo, cuántos más bajos como o mayúsculas quieres tener, cuántos números, y así sucesivamente. Entonces el nombre del paquete es Joy password complexity. En este curso, no vamos a usar esto porque eso es algo que puedes hacer por tu cuenta. Bien, nuestro nuevo punto final API está en buena forma, pero estamos almacenando nuestras contraseñas como texto plano, y esto es muy, muy malo. Entonces, en la próxima conferencia, voy a mostrarte cómo hash estas contraseñas. 6. Cómo usar hash de contraseñas: En esta conferencia, te voy a mostrar cómo hacer hash de contraseñas. Para ello, vamos a utilizar una biblioteca muy popular llamada B crypt. Entonces aquí en la terminal, vamos a instalar B crypt. Instalar. Tenga en cuenta la versión que estoy usando. Esa es la versión 5.1 0.1. Ahora aquí, voy a crear un archivo de playground, así aprenderás a trabajar con esta biblioteca BCRP, y luego vamos a tomar ese código y ponerlo en una ruta para hacer hash la contraseña de los nuevos usuarios Así que vamos a crear un nuevo archivo, hash dot js. En este archivo, primero, necesitamos cargar BCRP Esto conserva un objeto. Lo almacenamos aquí. Cripta B. Ahora para tener una contraseña, necesitamos una sal. ¿Qué es una sal? Bueno, imagina que nuestra contraseña es uno, dos, tres, cuatro. Cuando lo hash, imaginemos que obtendremos una cadena como esta. Ahora bien, este algoritmo hash es de una manera. Entonces si tenemos A, B, CD, no podemos descifrar esto y obtener uno, dos, tres, cuatro Entonces, desde el punto de vista de la seguridad, eso es genial. Si un hacker mira nuestra base de datos, no puede descifrar estas contraseñas hash. Sin embargo, pueden compilar una lista de contraseñas populares y hash de ellas. Y luego podrán mirar la base de datos de nuestra aplicación. Encuentran esta contraseña hash, y saben que ABCD representa uno, dos, tres, cuatro Entonces por eso necesitamos una SAL. Como SALT es básicamente una cadena aleatoria que se agrega antes o después de esta contraseña. Por lo que la contraseña hash resultante será diferente. Cada vez basado en asalto que se utilice. Bien, déjame mostrarte esto en acción. Entonces aquí llamamos punto cripta B Gen SLT. Tenga en cuenta que este método tiene dos versiones. El primero es asíncrono. El segundo es sincrónico. Como mejor práctica, siempre debes usar métodos asíncronos porque como te dije al inicio del curso, en aplicaciones de nodo, tenemos un solo hilo No queremos mantener ocupado ese hilo porque entonces no podemos atender a otros clientes. Entonces llamamos a GensLT como argumento. Pasamos el número de ceños fruncidos. Queremos ejecutar este algoritmo para generar el SLT. Cuanto mayor sea el número, más tiempo va a tardar en generar la sal. Y también el SOT será más complejo y más difícil de romper. Entonces el valor predeterminado es diez. Vamos a usar eso ahora porque se trata de un método asíncrono. Podemos o bien pasar callback aquí, y eso es lo que ves en su documentación oficial, así como una gran cantidad de tutoriales en la web Pero este método también tiene una sobrecarga que devuelve una promesa. Entonces, en lugar de pasar una devolución de llamada, obtenemos una promesa, la esperamos y luego obtenemos la sal Entonces ahora necesitamos envolver esto en una función acing como run. Bien, entonces bloqueemos esta sal en la consola. Y finalmente, llamemos a esta función run. Ahora, de vuelta en el nodo terminal tiene que Js. Entonces este es un ejemplo de sal. Se puede ver el número de rondas que utilizamos incluidas en la sal. Entonces, si usamos 20 aquí en vez de diez, tendríamos 20. Así que aquí tenemos una larga cadena aleatoria que se incluye como parte del hash de nuestras contraseñas Y con esto, cada vez que hash nuestra contraseña con un nuevo Salt, obtenemos resultados diferentes. Entonces ahora que tenemos un Salt, podemos usar esto para hash nuestra contraseña. Tenemos otro método aquí en este objeto cripta B que es hash. Entonces le damos nuestros datos. Imaginemos que nuestra contraseña es uno, dos , tres, cuatro, y dale la sal. Y nuevamente, mira, el tercer argumento puede ser una devolución de llamada. No vamos a usar esto. En cambio, vamos a obtener la promesa que se devuelve de este método. Entonces esperamos esa promesa y obtenemos la contraseña hash. Así que ahora vamos a registrar esto en la consola también. Hashed. Bien, de vuelta en el nodo terminal, hashed o chase Bien, mira, en la primera línea, tenemos nuestra sal. En la segunda línea, se puede ver la sal aquí también. Por lo que el SALT está incluido en la contraseña hash. La razón por la que esto se incluye es porque más adelante cuando queremos autenticar al usuario, queremos validar su nombre de usuario y contraseña Entonces ahí el usuario envía una contraseña en texto plano. Necesitamos volver a hash, pero necesitamos tener la sal original que se utilizó para generar este hash. Entonces, al comparar la contraseña de texto plano con la contraseña hash, B crypt necesita conocer la sal original que se usó para hash la contraseña Entonces ahora que ya sabes cómo funciona B Crypt, tomemos estas dos líneas y las pongamos en nuestro manejador de rutas Así que córtelos de aquí. Vamos a los usuarios punto js. Bien, aquí está nuestro objeto de usuario. Pasemos esas líneas aquí. Entonces generamos una sal, y luego necesitamos que tenga la contraseña. En lugar de uno, dos, tres, cuatro, vamos a usar la contraseña de punto de usuario. Esa es una contraseña de texto sin formato. Entonces lo hash con una sal y luego lo restablecemos. Entonces usuario punto contraseña. Ahora en la parte superior, también necesitamos importar cripta B, tan constante cripta B. Establecemos esto para que requiera Bcrypt. Ahora, aquí en Compass, quiero eliminar la colección del usuario porque todos los usuarios que tenemos hasta ahora, tienen contraseña de texto plano. Así que borra. Todo bien. Ahora de vuelta en la terminal, ejecutemos Node mod. Y luego aquí en Cartero, vamos a enviar una nueva solicitud S. Hermosa. Entonces aquí tenemos un nuevo usuario. Ahora de vuelta en Compass, vamos a refrescar la lista. Tenemos la colección del usuario, y aquí está nuestro nuevo usuario con una contraseña hash Hermoso. Por lo que hemos implementado este punto final para registrar nuevos usuarios. Ya terminamos aquí. A continuación, vamos a ver cómo autenticar a los usuarios 7. Autenticación de usuarios: Bien, así que aquí en la carpeta rutas, agreguemos un nuevo archivo. A esto lo llamamos dojs de inicio de sesión o auth dot js. O funciona, pero la auth es más común. Así auth Js. De nuevo, ahorras tiempo, voy a pedir prestado algún código Así que vayamos a los usuarios punto js. Voy a copiar todo el código que escribimos en esta sección, y luego pegaré en auth dot js Ahora antes de entrar en los detalles, vamos al punto índice JS. En el grifo, importe este nuevo módulo. Entonces Cs OT, configuramos esto para requerir rutas OT. Entonces, si tenemos alguna solicitud a este punto final, slash API OT o uno de sus endpoints secundarios, vamos a delegar esto al router OT Entonces el panorama general está hecho. Ahora veamos los detalles. Así que de vuelta en el módulo Auth, en la parte superior, primero, necesitamos validar el cuerpo de la solicitud Pero esta función validar la tenemos aquí, esta es la que importamos de nuestro módulo de usuario. Entonces esto está validando eso. En el cuerpo de la solicitud, tenemos tres propiedades, nombre, correo electrónico y contraseña. Y en la aplicación del mundo real, es posible que tengas otras propiedades como parte del registro de un usuario. Por lo que esta función de validar es para validar a un nuevo usuario. No es para validar el correo electrónico y la contraseña que esperamos en este punto final Entonces aquí necesitamos una función de validación diferente. Así que voy a quitar esta función de validar de aquí y definir una función de validación separada en este módulo. Ahora para ahorrar tiempo, voy a ir al módulo de usuario y copiar esa función de validar. Así que tenemos usuario validado. Vamos a copiar esto de nuevo al módulo Auth, pegarlo aquí, y luego cambiarlo para validar Ahora podemos cambiar el parámetro a solicitar. Ahora para este objeto de esquema, solo necesitamos dos propiedades, correo electrónico y contraseña. Entonces, eliminemos el nombre y ya terminamos. Así que volviendo a nuestro manejador de rutas, esta es nuestra primera validación A continuación, debemos asegurarnos que tenemos un usuario con un correo electrónico determinado. Entonces cargamos al usuario. Si no tenemos el usuario, así que aquí aplicamos el operador not. Si no tenemos el usuario, debemos enviar un error 400 al cliente, lo que significa que esa solicitud y el mensaje debe ser correo electrónico o contraseña no válidos. Tenga en cuenta que aquí, no estoy enviando un cuatro o cuatro, lo que significa que no se encuentra porque no queremos decirle al cliente por qué falla la autenticación. No queremos decir si este correo electrónico es correcto o la contraseña. Entonces no queremos decir que no tenemos un usuario con un correo dado. Nosotros solo le decimos al cliente que esta es una mala solicitud. No tiene los datos correctos para ser procesados. Entonces esto es para validar el nombre de usuario y correo electrónico en este caso A continuación, necesitamos validar la contraseña. Para eso, necesitamos usar BCRP. Entonces, eliminemos todo este código. Este objeto cripta B que tenemos tiene un método de comparación. Usamos esto para comparar una contraseña de texto sin formato con una contraseña hash Entonces nuestra contraseña de texto plano está en la solicitud de contraseña de punto cuerpo punto, y nuestra contraseña hash está en el usuario esa contraseña. Entonces, como viste antes, esta contraseña hash sí incluye el SLT Entonces cuando llamamos al método compare, B crypt va a obtener esa sal y usarla para descansar esta contraseña de texto plano. Si son iguales, entonces esto volverá cierto. Entonces aquí tenemos que esperar esta promesa y almacenar el resultado aquí en contraseña válida. Ahora bien, si la contraseña no es válida, nuevamente, vamos a devolver un error 400 con ese mensaje vago, correo electrónico no válido o contraseña Entonces solo voy a copiar esto y pegarlo aquí. Y finalmente, si llegamos esto a este punto, eso significa que este es un login válido. Entonces por ahora, solo quiero enviarle un valor simple, verdadero a la pelusa. 8. Prueba de la autenticación: Entonces, por ahora, probemos esta ruta de autenticación. Antes de eso, así un de punto js. Aquí, olvidé mencionar la alegría de carga. Entonces déjenme hacer esto rápidamente. Last Joy, establece esto para que requiera de Joy. Bien. Y en la parte inferior para validar la función, aquí necesitamos devolver el esquema dot validate request. Bien, entonces ya estamos todo listo. Vamos a abrir postmin. Entonces aquí voy a abrir una nueva pestaña. Seleccionemos post aquí. Déjame escribir el punto final. Es TP, host local OT, API OT. Y en el cuerpo de solicitud, voy a mandar a la GSN fuera. Entonces déjame seleccionar Json aquí. Y ahora tenemos dos parámetros. Entonces, el primero es el correo electrónico. El correo electrónico que hemos utilizado es un 23, cuatro, cinco, seis, siete, a la tasa gmail.com Y nuestra contraseña es uno, dos, tres, cuatro, cinco. Entonces déjame enviar esta solicitud, SN. Hermoso. Tenemos un estatus 200. Bien. Y aquí está nuestra respuesta a través de. Ahora, permítanme cambiar la contraseña aquí a otra cosa como 67 y luego volver a enviar la solicitud. Ver, tenemos una solicitud 400 mala y el comando genérico, que es correo electrónico o contraseña inválidos. Ahora cambiemos el correo electrónico a otra cosa con la contraseña correcta. Entonces algo como esto. Y déjenme volver a enviar la solicitud. Así que envía. Ver, nuevamente, tenemos una solicitud 400 mala y el mensaje genérico que es correo electrónico o contraseña no válidos. Entonces nuestro punto final de autenticación está funcionando bien. En la siguiente conferencia, vamos a ver la respuesta que estamos enviando aquí y cambiarla a algo lo que llamamos token web adyacente. 9. Tokens web JSON: Entonces tenemos un punto final para autenticar a los usuarios. Ahora, necesitamos modificar la respuesta aquí, y en lugar de devolver un valor verdadero, necesitamos devolver un token web JCN AJCN webtoken es básicamente una cadena larga que identifica a un usuario Como metáfora, puedes pensarla como tu licencia de conducir o tu pasaporte Es muy similar a eso. Entonces cuando el usuario inicia sesión en el servidor, tiramos esta web de JCN tooken, que es como una licencia de conducir o pasaporte, se la damos al cliente y luego le decimos, Oye, próxima vez que quieras volver aquí y llamar a uno de nuestros puntos finales de API, necesitas mostrar tu Necesitas mostrar tu licencia de conducir. Esta es tu identificación. Entonces en el cliente, necesitamos almacenar este token web JCN, que es una cadena larga, podamos enviarlo de vuelta al servidor para futuras llamadas a la API Ahora, el cliente puede ser una aplicación web o una aplicación móvil. Si se trata de una aplicación web, si estás construyendo una aplicación con angular o react, puedes usar almacenamiento local. Ese es un lugar de almacenamiento especial que está disponible en todos los navegadores que existen. Si estás construyendo una aplicación móvil, tienes una opción similar dependiendo de qué plataforma uses. Entonces ahora déjame mostrarte un ejemplo de AjcnWbtken. Dirígete sobre tojwt dot IO. En este sitio web, aquí tenemos un depurador para trabajar con JS y WebTkens Entonces aquí en la sección codificada, se puede ver un ejemplo real de AJCN Web tooken Esta cadena larga que ves en la sección codificada representa un JCNoBr así que cuando decodificemos esto, obtendremos ¿Bien? Ahora podemos ver que esta cadena tiene tres partes, y cada parte es código de color. Entonces la primera parte es roja, la segunda parte es morada, y la tercera parte es azul. En el lado derecho, se puede ver esta cadena decodificada. Entonces la parte roja es lo que llamamos el encabezado de un token web JCN En esta cabecera, tenemos dos propiedades. Uno es L, que es la abreviatura de algoritmo que determina el algoritmo utilizado para codificar este token. El tipo es GWT, que es el token web JCN Ahora nunca tenemos que preocuparnos por este encabezado. Es sólo un estándar. Lo que nos importa es la segunda parte, la carga útil, que es la parte morada. Entonces aquí tenemos un objeto JCN con tres propiedades, sub, que es como un ID de usuario, nombre y Admin Ahora bien, la carga útil que ves es diferente a la carga útil que tengo porque he modificado el fold JS y webtog y está en este Entonces generé un token web personalizado, póngalo aquí. Lo que quiero señalar aquí es que esta carga útil incluye propiedades públicas sobre el usuario. Al igual que en tu pasaporte, tienes algunas propiedades sobre ti, como tu nombre, tu fecha de nacimiento, tu lugar de nacimiento, y así. Así que tenemos exactamente el mismo concepto ren adyacente web token. Puede incluir algunas propiedades públicas básicas sobre el usuario. Y con esto, cada vez que enviamos un token del cliente al servidor, podemos extraer fácilmente el ID de usuario de la carga útil. Si necesitamos saber el nombre del usuario, entonces simplemente podemos extraerlo aquí también. No tenemos que consultar la base de datos, enviar este ID para obtener un objeto de usuario y luego extraer la propiedad name. De la misma manera, si quieres saber si el usuario es un usuario administrador o no, podemos incluirlo aquí. Entonces nuevamente, no tenemos que enviar una consulta extra a la base de datos para ver si el usuario con un ID dado es admin o no. Ahora podría estar preocupado por este enfoque desde el punto de vista de la seguridad, porque puede pensar que cualquiera puede simplemente establecer esta propiedad admin por sí mismos en true, y luego serán tratados como admin en el servidor. Pero no es así como funcionan los ptocanos de Jason. La tercera parte de este token Web JCN, que está en azul, es una firma digital Esta firma digital se crea a partir del contenido de este JCN WebTKEN junto con una clave secreta o privada La clave secreta o privada solo está disponible en el servidor. Entonces, si un usuario malintencionado obtiene el JCN WebTKEN y modifica la propiedad admin, la firma digital no será válida porque se modifica el contenido del JCN Ahora necesitamos una nueva firma digital, pero el hacker no puede generar esta firma digital porque necesitarán la clave privada, que solo está disponible en el servidor. Entonces, si no tienen acceso al servidor, no pueden crear una firma digital válida. Y cuando envíen este token Web JCN templado al servidor, el servidor declinará eso El servidor dirá, este no es un token web JCN válido. Entonces así es como funcionan los tokens Web JCN. 10. Generación de tokens de autenticación: Entonces en esta página, si miras las bibliotecas, aquí encontrarás diferentes módulos o bibliotecas para diferentes plataformas. Entonces, si te desplazas hacia abajo, verás que tienes Tad net one C B, C, C plus, node, y así sucesivamente. Entonces abramos el terminal e instalemos JCN webtook y BM e instalemos ASN Bien, si miras el paquete un JSON, verás que la versión que estamos usando es 9.0 0.2. Entonces vamos a cerrar esto. Tenemos la ruta para autenticar a los usuarios. Ahora, necesitamos crear un JCN WebTKEN antes de enviar una respuesta al cliente Entonces antes de eso, necesitas cargar JCN WebTKEN. Entonces en la parte superior, requieren Jason rep, estrangularlo y almacenarlo en una constante llamada JWT Genial. Ahora aquí, usaremos el método sinusoidal de JWT. Entonces JW punto seno por lo que aceptará dos argumentos. primero es la carga útil y el segundo es el rey secreto o privado. Entonces la carga útil podría ser una cadena simple o podría ser un objeto como el que ves aquí. Entonces hagamos nuestro objeto con una sola propiedad. Incluiremos ID de subrayado, y lo enviaremos al ID de subrayado de punto de usuario Ahora, según el segundo argumento, enviaremos esto a una cadena. Pero idealmente, no deberías almacenar tu clave secreta o privada en tu código fuente. Posteriormente, te mostraré cómo almacenar esto en un ambiente donde o. pero por ahora, pongamos esto en secreto de JWT No necesita ser clave secreta JWT. Podría ser cualquier cosa, cualquier cuerda. Pero por ahora, usemos esto. Entonces hemos utilizado un método de signo, y como resultado, obtenemos un token. Así que vamos a almacenarlo en constante y lo llamaremos token. Y ahora regresaremos o enviaremos la respuesta a nuestro cliente como gancho. Entonces hay esto de vuelta a la terminal. Vamos a correr hacia abajo. Ahora, vamos a cartero. Aquí le enviaremos el correo electrónico y contraseña correctos a esta ruta de autenticación. Entonces vamos a mandar esto. Y aquí está nuestro token web JCN. Entonces déjame copiar esto. Y volvamos al depurador. En esta sección codificada, solo puedes eliminar esta y pegar la que copiamos. Y aquí, en la sección decodificada, puedes ver nuestro objeto que enviamos como token así aquí tenemos la propiedad ID, que se establece en el ID del objeto en la base de datos de Mongaim Y además, tenemos IAT que es la hora actual y la hora en la que se crea este token Esto se utiliza para H el token. Por lo que hemos creado con éxito el token y lo enviamos como respuesta a nuestro clima. En el siguiente video, te mostraré cómo incluir esta clave secreta en una variable de entorno. 11. Almacenamiento de secretos en variables de entorno: Anteriormente en el curso, cuando hablaba de temas avanzados Express, te presenté un paquete de nodos llamado Config. Utilizamos este paquete para almacenar los ajustes de configuración de nuestra aplicación en archivos JSON o variables de entorno. Entonces en esta conferencia, vamos a sacar esta clave secreta y almacenarla en una variable de entorno porque como te dije antes, nunca debes almacenar tus secretos en tu base de código. De lo contrario, estos secretos son visibles para cualquiera que tenga acceso a tu fuente. Así que de vuelta en el terminal, vamos a instalar el módulo config. Puedo anotar el número de versión que es 3.3 0.11. Ahora primero, necesitamos crear una nueva carpeta que sea config. En esta carpeta, agregamos un archivo de configuración predeterminado que es punto predeterminado JSM Así que un simple objeto SN. Podríamos tener varios ajustes aquí. Pero por ahora, solo quiero agregar una configuración. Esa es la clave secreta de JWT. Ahora en este archivo GSN predeterminado, vamos a establecer esto en una cadena vacía El valor real no está aquí. Entonces aquí solo estamos definiendo una plantilla para todos los ajustes en nuestra aplicación. Ahora necesitamos crear otro archivo que sea personalizado variables de entorno punto JS. Anote la ortografía, asegúrese de hacerlo bien. De lo contrario, lo que les voy a mostrar en esta conferencia no va a funcionar en su máquina. Entonces como te dije antes, en este archivo, especificamos el mapeo entre la configuración de nuestra aplicación y las variables de entorno. Entonces voy a volver a nuestro punto predeterminado Son, copia todo esto, pegarlo aquí. Entonces esta es la estructura de nuestro objeto de configuración de aplicaciones. Ahora queremos mapear esto a la configuración a una variable de entorno llamada clave secreta JWT Pero como práctica recomendada, nuevo, como te dije antes, es mejor prefijar esto con el nombre de nuestra aplicación para que no termines por una configuración de aplicación anulando otra configuración de aplicación Así que las ruedas justas alinean la clave secreta JWT. Ahora con esto, podemos volver a nuestro módulo Auth, así que Js. Entonces este es un lugar en el que hemos hecho referencia al secreto vamos a reemplazar esto con una llamada al método Confic dot get Entonces primero en la parte superior, necesitamos importar el objeto config. Entonces Cs config. Configuramos esto para que requiera confit. Bien. Ahora, de vuelta en el método post, llamamos config dot cat y pasamos el nombre de la configuración de la aplicación. En este caso, JWT secreto K. Así que ahora, esto no es un secreto. Es un nombre de la configuración de nuestra aplicación. El valor real, el secreto real estará en una variable de entorno. Un último cambio, tenemos que ir a index dot js. Cuando se inicia la aplicación, desea asegurarse de que esta variable de entorno esté establecida. De lo contrario, tenemos que terminar la aplicación porque nuestro punto final de autenticación no puede funcionar correctamente. Una vez más, en la parte superior, cargamos el módulo config. Config, configuramos esto para que requiera config. Ahora, una vez más, vamos a llamar a config dot get pass the name of the application setting JWT secret key Ahora bien, si esto no está definido, vamos a registrar un error fatal. La clave secreta JWT no está definida. Y entonces tenemos que salir del proceso. Anteriormente, se aprende sobre este objeto de proceso. Este es uno de los objetos globales en node. Aquí tenemos un método llamado exit. Le damos un código, cero indica éxito. Cualquier cosa menos cero significa fracaso. Muy a menudo, usamos exit one si quieres salir del proceso en caso de error. Por lo que actualmente, no he establecido esta variable de entorno. Ejecutemos la aplicación y veamos qué pasa. Entonces Norman index dot JS, Bien, mira, tenemos este error fatal. La aplicación se estrelló, esperando cambios en los archivos antes de comenzar. Ahora se podría pensar que la aplicación sigue ejecutándose porque Norman sigue ahí. No se termina. Pero si vas a Cartero y envías una solicitud SDDP a la aplicación, verás que nuestra aplicación no responde Entonces, si la aplicación falla, Norman sigue funcionando. Norman sigue corriendo. Déjame mostrarte a lo que me refiero. Entonces si en lugar de no mod ejecuto aplicación con nodo veo que la aplicación se estrelló, y ahora estamos de vuelta en la terminal Por lo que no estamos respondiendo a ninguna solicitud recibida de los clientes. Ahora, vamos a establecer la variable de entorno. Como te dije antes, en Mac, usas Exportar, en Windows, usas set para símbolo del sistema y columna ENV dólar para Power Shell Columna dólar ENV, ruedas justas, subrayado, clave JWT Secret. Nosotros también establecemos esto. Digamos mi llave de seguridad. Ahora volvamos a ejecutar la aplicación. Índice de nodos o Js. Bien, hermosa. Lo conectamos a Mongadib y si volvemos a Cartero y enviamos otra solicitud a Login, aquí está nuestro queso válido y token web que está firmado con nuestra clave secreta, cual se almacena en 12. Establecer encabezados de respuesta: Entonces en la implementación actual, cuando el usuario inicia sesión, generamos un token web JCN y lo devolvemos en el cuerpo de la respuesta Ahora llevemos esta aplicación al siguiente nivel. Imaginemos cuando el usuario se registre, queremos asumir que está conectado, para que no tenga que iniciar sesión por separado. Por supuesto, este requisito no aplica a todas las solicitudes. En ocasiones se quiere exigir al usuario que verifique su dirección de correo electrónico. Entonces después de que se registren, les envías un correo electrónico, ellos dan clic en un enlace. Entonces el proceso es diferente. Pero en este curso, imaginemos que Fair Wheels es una aplicación que se ejecuta localmente en un alquiler de autos. Entonces las personas que usan esta aplicación son personas que trabajan en este alquiler de autos. No necesitamos verificar su dirección de correo electrónico. Entonces, el primer día que se unen a la tienda, necesitan crear una cuenta, y boom, están logueado. Entonces vayamos al módulo de nuestro usuario. Bien, aquí está el método post. Aquí es donde registramos un nuevo usuario. Ahora bien, si nos fijamos en la respuesta que estamos regresando aquí, estamos devolviendo un objeto con estas tres propiedades. Ahora podemos agregar el token web JCN como otra propiedad aquí, pero eso es un poco feo porque no es propiedad de un usuario Un mejor enfoque es devolver el token web JCN en un encabezado SDDP Así que al igual que tenemos encabezados en nuestra solicitud, también tenemos encabezados en nuestro objeto de respuesta. Entonces voy a volver a nuestro módulo Auth y tomar prestada esta línea de código para generar el token Así que copia esto ahora de nuevo al módulo del usuario. Antes de enviar la respuesta al cliente, generamos el token y luego llamamos a un encabezado de punto de respuesta. Con esto, podemos establecer un encabezado. Ahora bien, para cualquier encabezado personalizado que definamos en nuestra aplicación, debemos prefijar estos encabezados con X. Ahora le damos un nombre arbitrario como autenticación o token. Este es el primer argumento, que es el nombre del encabezado. El segundo argumento es el valor, que es en este caso, nuestro token. Entonces con este simple cambio, establecemos este encabezado y luego enviamos esta respuesta al cliente. ¿Bien? Ahora en la línea 20, estamos usando JWT así como el módulo confit Entonces necesitamos importar estos en la parte superior. Tan constante TWT configuramos esto para requerir JCN web tooken. Y de manera similar, constant config, configuramos esto para requerir confit Ahora vamos a probar esto. Entonces en la última conferencia, ejecuté la aplicación con nodo en lugar de ni modo. Entonces mis cambios no son visibles. Entonces necesitamos detener la aplicación y ejecutarla con modo nodo. Bien, hermosa. Ahora, de vuelta en Cartero aquí en esta pestaña para registrar un usuario, voy a cambiar este correo electrónico a un correo que no he registrado antes Enviados. Bien, échale un vistazo. Entonces aquí está el cuerpo de la respuesta exactamente como antes. Ahora en el Look Headertab, tenemos este nuevo encabezado, X token Y esto está configurado para nuestro JCN WebTKEN. Así que en nuestra app cliente, cuando registramos un usuario, podemos leer este encabezado. Podemos almacenar este JCN WebTGen en el cliente. Y la próxima vez que vamos a hacer una llamada API, enviaremos esta al servidor. 13. Encapsulación de lógica en modelos de manguesa: Ahora, hay un problema en nuestra implementación actual. En el módulo del usuario en la línea 22, así es como generamos un token web JCN Tenemos exactamente el mismo núcleo en el módulo Auth en la línea 20. Ahora mira la carga útil de este token web JCN. En esta carga útil, actualmente, solo tenemos la propiedad ID. Lo más probable es que mañana vamos a agregar otra propiedad en este pago tal vez el nombre del usuario, tal vez su dirección de correo electrónico, tal vez su rol. Queremos saber si hay un usuario admin o no. Con la implementación actual, cada vez que queremos cambiar esta carga útil, tenemos que recordar que tenemos que ir a otro módulo y hacer exactamente el mismo cambio. Y a la larga, vas a olvidarte de estos requisitos. Entonces en esta conferencia, voy a mostrarles cómo encapsular esta lógica en un solo lugar Ahora bien, ¿a dónde debemos mover esta lógica? Un programador aficionado puede pensar, Bien, voy a crear una función como generar token de autenticación, poner esta función en algún lugar que podamos reutilizar, tal vez en otro módulo que podamos importar tanto en la Tierra como en los módulos de usuario. Y con esto, tenemos la lógica en un solo lugar. Bueno, eso es cierto. Eso funciona. Pero con este enfoque, terminarás con un montón de funciones colgando por todo el lugar. En la programación orientada a objetos, tenemos un principio llamado principio de experto de información. Eso significa un objeto que tiene suficiente información y es un experto en un área determinada. Ese objeto debe ser responsable tomar decisiones y realizar tareas. Como ejemplo del mundo real, piensa en un chef. Un chef tiene un conocimiento de cocina. Por eso el acto de cocinar en un restaurante lo realiza un chef y no por un mesero El mesero no tiene el conocimiento adecuado, la información correcta sobre cocinar en un restaurante Entonces, si el chef es un objeto, debemos darle el acto de cocinar al chef. Ahora, toma este principio y aplícalo en este código. Entonces aquí, como parte de crear este Chase y token web, ¿qué necesitamos en la carga útil? Necesitamos el ID del usuario. Mañana, es posible que necesitemos el nombre del usuario o su correo electrónico. Entonces toda esta información se encapsula aquí en el objeto user. Entonces es el objeto de usuario el que debería ser responsable de generar este token de autenticación. Entonces la función que escribí aquí, generar token de autenticación, esa función no debería estar colgada en algún lugar de un módulo. Ese debería ser un método en el objeto de usuario. Entonces aquí tenemos un objeto de usuario que cargamos desde la base de datos. Necesitamos agregar un método en este objeto de usuario como este. Usuario que genera token de autenticación. Y esto nos va a dar una ficha, simple como eso. Ahora bien, ¿cómo podemos agregar esto? Tenemos que ir a nuestro módulo de usuario donde definimos el modelo de usuario y hacer un simple cambio ahí. Todo bien. Entonces aquí en nuestro modelo de usuario, necesitamos extraer la definición de este esquema y ponerlo en una constante separada porque vamos a trabajar con ese separado. Entonces voy a seleccionar todo este coe. Entonces, al crear el modelo de usuario como segundo argumento, pasamos el esquema de usuario, y aún no lo hemos creado. Eso lo vamos a hacer ahora. Así esquema de usuario constante, y establecemos esto a esta expresión así. Bien. Así que aquí está nuestro esquema de usuario. Ahora, desea agregar un método en este esquema. Así esquema de usuario que tenemos una propiedad, métodos, esto devuelve un objeto. Podemos agregar pares de valores clave adicionales en este objeto. Así podemos agregar una clave, generar autenticación o token. Ponemos esto a una función. Así par de valor clave. Cuando hacemos esto, entonces nuestro objeto de usuario tendrá un método llamado generar token de autenticación. Ahora aquí, en esta función, podemos tener parámetros. Entonces si tenemos un parámetro aquí, entonces al llamar a este método, podemos pasar argumentos. En este caso, no necesitamos ningún parámetro, así que solo necesito agarrar esta lógica para generar el token, obtenerlo de aquí y moverlo dentro de este nuevo método. Entonces aquí en la carga útil, necesitamos la D del usuario. ¿Cómo conseguimos eso? Bueno, este método será parte del objeto de usuario. Entonces para hacer referencia al objeto en sí, reemplazamos usuario con esto. Y esto significa que aquí debes usar la sintaxis de la función regular. No se puede reemplazar esto con una función de flecha. Porque como te dije antes, las funciones de flecha no tienen su en esto. Esto en una función de flecha hace referencia a la función de llamada. Por lo general, usamos funciones de flecha para funciones independientes. Si desea crear un método que sea parte de un objeto, no debe usar una función de flecha. Ahora, vamos a revertir esto. Entonces aquí tenemos la ficha, y finalmente, la devolvemos tan simple como eso. Aquí estamos haciendo referencia a los módulos JWT y conflicto. Entonces necesitamos importar esto en la parte superior. Entonces voy a volver a nuestro módulo Auth en la parte superior. Ya no necesitamos estas declaraciones requeridas. Entonces voy a conseguir estos de aquí. Y ponlos encima del módulo de usuario. Ahora, de vuelta en el módulo de autenticación, así generamos el token y luego lo enviamos al cliente. Necesitamos hacer los mismos cambios en el módulo de nuestro usuario. Módulo del usuario, eliminamos esta línea y establecemos el token al usuario que genera AuthToken Entonces, finalmente, probemos esto y asegurémonos de que todo esté funcionando. Entonces voy a registrar un nuevo usuario aquí. Enviar, hermosa. Y aquí está nuestro token de autenticación. 14. Middleware de autorización: Por lo que al inicio de esta sección, decidimos proteger las operaciones, que modifican los datos y los ponen a disposición únicamente de los usuarios autenticados Entonces vamos a nuestras empresas punto CHASE Piers el método post para crear una nueva empresa Este punto final de API solo debe ser llamado por un usuario autenticado Entonces, ¿cómo podemos hacer cumplir esto? Bueno, aquí, hicimos alguna lógica como esta. Necesitamos leer los encabezados de las solicitudes. Entonces este objeto request tiene un método llamado header. Aquí, especificamos el nombre del encabezado, es decir X token. Esperamos un token web JCN almacenado en este encabezado. Entonces almacenamos esto como token constante. Ahora, queremos validar esto. Si esto es válido, entonces damos acceso a este punto final de API. De lo contrario, devolveremos una respuesta como esta. Respuesta para el código de estado de cuatro oh uno, lo que significa que el cliente no tiene las credenciales de autenticación para acceder a este recurso. Entonces este es el panorama general. Ahora no queremos repetir esta lógica al inicio de cada manejador de rutas que modifique Entonces necesitamos poner esta lógica en una función de middleware. Recuerda, funciones de middleware, hablamos ellas en la sección llamada Temas avanzados Express Entonces ponemos esta lógica en una función de middleware, y luego podemos aplicar esa función en manejadores de ruta que necesitan modificar datos. Déjame mostrarte. Así que vamos a sacar esto de aquí. Bien, aquí queremos agregar una nueva carpeta llamada middleware Así que ponemos aquí todas nuestras funciones de middleware. En esta carpeta, teníamos un nuevo archivo t punto tiene. Ahora aquí queremos definir una función llamada OT que toma tres parámetros, request response, y next, que usamos para pasar el control a la siguiente función de middleware en la canalización de procesamiento de solicitudes Si este concepto te suena desconocido, necesitas volver a la sección llamada Temas Avanzados Express porque ahí exploramos las funciones de middleware Entonces aquí en esta función, debemos implementar esta lógica. Obtenemos la ficha. Lo más probable es que no tengamos una ficha en absoluto. En este caso, devolvemos una respuesta 41 con un mensaje como este. Acceso denegado. No se proporcionó ningún token. Entonces esto ayuda al cliente a averiguar por qué no puede acceder a este recurso. Ahora bien, de lo contrario, hay una ficha. Tenemos que verificar que se trata de un token válido. Entonces aquí necesitamos usar nuestro módulo de token web JCN. Entonces, en la parte superior, requeramos el token web JCN y lo almacenemos en JW Ahora aquí llamamos a jwt punto Verifi. Como primer argumento, pasamos el token, y como segundo argumento, pasamos la clave secreta para decodificar este token. Así que almacenamos esa clave secreta en una variable de entorno. Necesitamos usar un módulo de configuración para leerlos. Así que requiere config y guárdala aquí. Así que al igual que antes, llamamos config dot g JWT Ccret key Ahora, este método de verificación verificará nuestro Si es válido, lo decodificará y devolverá la carga útil. Entonces aquí obtenemos la carga útil descifrada. No obstante, si este token no es válido, lanzará una excepción. Así que necesitamos envolver esta línea con un bloque try cache. Así que prueba Cache, obtenemos una excepción. Si llegamos hasta aquí, queremos decirle al cliente que se trata de un token no válido. Establecemos este estado a lo 400 porque hay una mala solicitud porque lo que nos envía el cliente no tiene los datos correctos. Así que envía token no válido. Nuevamente, con este mensaje de error, podemos solucionar los problemas de autenticación Entonces, si en el cliente, no podemos acceder a un punto final de API dado, veremos el mensaje de error. Nos damos cuenta de que enviamos un token no válido. Después veremos la lógica en el cliente donde obtenemos el token y lo enviaremos al servidor. Entonces este es nuestro bloque de caché. Ahora, de vuelta al tri bloque, aquí tenemos la nómina. Entonces podemos poner eso en la solicitud. Entonces nuestro objeto request, le agregamos la propiedad user, y lo configuramos a esta decodificación Entonces antes, colocamos solo el ID del usuario en la carga útil. Déjame mostrarte. Así que vayamos a nuestro módulo de usuario. Aquí está nuestro esquema de usuario. Agregamos este método de generar token de autenticación. Creamos el JCN WebTKEN y esta es nuestra carga útil. Entonces cuando descodificamos este JWT, este es el objeto que obtendremos Y pondremos esto en la solicitud como objeto de usuario. Así que en nuestro manejador de rutas, podemos acceder a request dot user dot underline dot ID y ¿Bien? Entonces, en el bloque tri, establecemos request dot user, y luego necesitamos pasar el control a la siguiente función de middleware en la canalización de procesamiento de solicitudes En este caso, ese es nuestro manejador de rutas. Entonces llamamos siguiente. Entonces como te dije antes, en las funciones de middleware, o terminamos el ciclo request response sl o pasamos el control a la siguiente función de middleware Ahora, solo un pequeño problema en este código, en caso de que no tengamos un token, vamos a enviar esta respuesta al cliente. Pero quiero asegurarme de que salgamos de esta función. Bien, hemos terminado con nuestra función de middleware. Ahora al final, establecemos las exportaciones de punto de módulo a OTO un atajo para eso es configurarlo aquí mismo. Entonces establecemos las exportaciones de punto del módulo, lo configuramos en una función. No necesitamos un em aquí. Y entonces podremos deshacernos de la línea 17. Hecho. 15. Protección de rutas: Entonces ahora que tenemos una función de middleware, podemos ir al index dot JS, mira, aquí estamos aplicando funciones de middleware Entonces podemos agregar eso aquí, y luego se ejecutará antes de cada manejador de ruta Pero no queremos hacer esto porque no todos los endpoints API deben estar protegidos Algunos de nuestros endpoints API deben ser públicos, como registrar un usuario o iniciar sesión u obtener la lista de empresas o clientes Entonces, en este caso, queremos aplicar esta función de middleware selectivamente a ciertos Así que volvamos al módulo de la compañía, aquí está nuestro manejador de rutas de correos El primer argumento es una ruta. El segundo es opcionalmente middleware, y el tercero será el controlador de ruta real Así que vamos a ir en la parte superior, impartir esta función de middleware . Por lo tanto requieren. Ahora necesitamos subir un nivel y luego ir a la carpeta middleware y cargar el módulo Earth Lo conseguimos y lo ponemos aquí. Y finalmente, aquí en el método post, pasamos OT como una función de middleware para ser ejecutada antes que esta otra función de middleware, que es en este caso, que es en este caso, Entonces ahora vamos a probar esto de nuevo en Cartero. Voy a abrir una nueva pestaña, enviar una solicitud de publicación al punto final de la compañía. Así STDP host local, API Empresas. Ahora, en este caso, no me preocupa el cuerpo de la solicitud. Solo quiero saber si podemos llamar a este punto final API o no. Así que envía Bien, mira, tenemos este 401 o error no autorizado. Y aquí está el mensaje de error. Acceso denegado, Noto puede proporcionar. Ahora vamos a proporcionar un token no válido. Entonces vamos a la pestaña de encabezados, establecemos la clave que es X token. Pongo un token no válido, envío, nos dieron 400 o mal pedido con este mensaje. Token no válido. Hermoso. Ahora por fin, volvamos a nuestro registro, usa una pestaña. Obtuvimos un token de autenticación válido. Entonces copiemos esto de nuevo a la tercera pestaña. Póngalo aquí y luego envíelo. Bien, ahora tenemos una mala solicitud, pero esto no es por la autenticación. Esto se debe a que esperábamos el nombre propiedad en el cuerpo de solicitud. Entonces, si agrego un objeto JSON aquí en el cuerpo, nombre nueva compañía. Ahora, deberíamos ser buenos. Enviar. Entonces obtuvimos una respuesta de 200, y esta es la nueva compañía. Entonces, como ejercicio, quiero que apliquen esta función de middleware a otros manejadores de ruta que 16. Conoce al usuario actual: En muchas aplicaciones, hay veces que necesitamos obtener información sobre el usuario actualmente conectado. Entonces en esta conferencia, vamos a agregar un nuevo punto final de API para obtener el usuario actual. Entonces vayamos a nuestro módulo de usuarios. Actualmente, solo tenemos un manejador de rutas. Eso es para crear un nuevo usuario. Ahora necesitamos agregar otro manejador para los métodos get. Ahora aquí, agrega un camino o ruta. Podemos pasar un parámetro, pero esto significa que el cliente debe enviar el ID al servidor. Si bien este enfoque está perfectamente bien, hay veces que quizás por razones de seguridad, no quieres tener un endpoint como este porque entonces puedo enviar el ID de otro usuario y mirar su cuenta donde podría haber alguna información que quizás no debería ser visible para mí. Entonces el enfoque que usamos con bastante frecuencia para obtener información sobre el usuario actual es tener un punto final API como yo. Con esto, el cliente no va a enviar el ID de usuario. Lo conseguimos de la Web de JCN tomó. Entonces no puedo forjar JCN WebTKEN de otra persona porque te dije que para poder hacerlo, necesito crear una nueva firma digital para ese Entonces agreguemos el manejador de ruta, solicitud asíncrona y respuesta va a este bloque de código Ahora, este punto final de API solo debería estar disponible para usuarios autenticados Entonces aquí necesitamos agregar nuestro middleware OT. En la parte superior, carguemos OT desde middleware Auth. Solo para aclarar, aquí, el autor representa la autorización, no la autenticación porque la autenticación se trata de validar la contraseña del nombre de usuario Aquí, queremos ver si el usuario tiene permiso para acceder a un recurso o no, y esa es autorización. Agregamos nuestro middleware aquí. Ahora con este middleware, si un cliente no envía un token web JCN válido, nunca llegaremos a este No obstante, si llegas hasta aquí, como viste en la implementación de esta función de middleware aquí, tendremos request dot user object Para que podamos acceder a la propiedad ID aquí. Entonces, en lugar de pasar la propiedad ID en la ruta o en la ruta, obtenemos de request dot user dot ID, que en realidad proviene de nuestro token web JSON. Entonces este es un enfoque más seguro. Ahora, queremos encontrar un usuario por el ID dado. Entonces llamamos usuario punto fino por ID. Pre pasar este valor, luego esperar la promesa y obtener el objeto de usuario aquí. Ahora, no queremos devolver la contraseña del usuario al cliente. Entonces aquí, llamemos a Select y excluyamos la propiedad de contraseña. En tu aplicación, tal vez quieras excluir otras propiedades también. Tal vez dirección, tal vez número de teléfono. Entonces aquí tenemos un objeto de usuario. Por último, enviamos esto al cliente. Así que envía usuario tan simple como eso. Ahora, vamos a probar esto. Entonces aquí en Cartero, voy a agregar una nueva pestaña, enviar una solicitud Get a Local host para 3,000 usuarios de API me. Ahora, inicialmente, no quiero enviar un JCN WebTKEN. Por lo que enviar Xs negó ningún token, siempre. Hermoso. Ahora vamos a la pestaña de encabezados. Agrega X o token aquí, y luego pasa una ficha de queso y web SN. Esta es mi cuenta de usuario. Podemos ver que la contraseña está excluida. 17. Cerrar sesión de usuarios: Entonces en nuestro módulo Auth, definimos esta ruta para autenticar ¿Qué pasa con cerrar la sesión de los usuarios? ¿Necesitamos una ruta separada para eso? No, porque no estamos almacenando este token en ningún lugar del servidor. Por lo tanto, no necesitamos un controlador de ruta separado para eliminar este token Entonces, técnicamente, necesita implementar la función de cierre de sesión en el cliente, no en el servidor. Entonces en la aplicación cliente, cuando el usuario quiere cerrar sesión, simplemente borra ese token del cliente. Ahora, he visto cursos y tutoriales que te enseñan a almacenar este token en el servidor en la base de datos. Esta es una muy mala práctica porque estos tokens son como claves que dan a un cliente acceso a endpoints API protegidos Si un hacker puede acceder a tu base de datos, puede ver todos estos tokens para usuarios autenticados Ni siquiera necesitan saber la contraseña de un usuario. Simplemente pueden obtener su token de autenticación y enviarlo al servidor para ejecutar la solicitud en nombre de un usuario. No debes almacenar tokens en tu base de datos. Y si sabes lo que estás haciendo y realmente quieres almacenar el token en la base de datos, asegúrate de cifrarlo. Asegúrate de hash. Al igual que las contraseñas. Almacenar un token en un texto plano en base de datos es como obtener el pasaporte o licencia de conducir de todos los usuarios, ponerlos en un lugar central, y luego cualquiera, cualquier usuario malicioso que tenga acceso a ese lugar central, simplemente puede obtener estos pasaportes Pueden obtener esta licencia de conducir e imitar a otros usuarios, otros clientes Entonces una vez más, no almacene los tokens en el servidor, los almacene en el cliente. Y como mejor práctica de seguridad, siempre que estés enviando el token del cliente al servidor, asegúrate de usar HTTPS. Entonces un hacker sentado en el medio oliendo tráfico, no puede leer el token enviado desde el cliente al servidor, por lo que los datos se cifran entre el cliente y el 18. Autorización basada en roles: Hasta el momento, hemos implementado la autenticación y autorización con éxito. Ahora llevemos esta aplicación al siguiente nivel. Imaginemos que ciertas operaciones como eliminación de datos solo pueden ser realizadas por Administradores. Entonces déjame mostrarte cómo implementar una autorización basada en roles. Primero, tenemos que ir a nuestro modelo de usuario. Entonces este es nuestro esquema de usuario. Actualmente, contamos con tres propiedades, nombre, correo electrónico y contraseña. Ahora, necesitamos agregar otra propiedad para ver si un usuario determinado es un administrador o no. Así que vamos a agregar una nueva propiedad es admin de tipo Boolean. Entonces ese es el primer paso. Ahora voy a ir en Mongo DB Compass, agarrar a uno de estos usuarios y convertirlos en un administrador. Así que edita. Voy a agregar un campo después de la contraseña, y el pedido realmente no importa. Así es admin y por defecto, se puede ver el tipo de esto es cadena. Vamos a cambiar eso a booleano. Entonces digamos esto a true y luego finalmente apliquemos la actualización. Entonces aquí tengo un usuario que es administrador. Ahora, cuando el inicio de sesión, quiero incluir esta propiedad en nuestra carga útil JSON Web Token. Así que la próxima vez que envíen este JCN WebTken al servidor, podemos extraer esta propiedad directamente del token No tenemos que obtener el ID, entrar en la base de datos y ver si son admin o no. Y nuevamente, como te dije antes, con la firma digital incluida en un webtken de JCN, un usuario malintencionado no puede cambiar el valor de su administrador para su cuenta de Si hacen algún cambio, tienen que regenerar la firma digital, y esto requiere conocer la clave privada que almacenamos en una variable de entorno en el servidor Ahora, de vuelta en nuestro módulo de usuario, cuando generemos el token de autenticación, queremos agregar esta propiedad en la carga útil. Así que aquí está nuestra carga útil. Vamos a agregar una nueva propiedad es admin. Ponemos esto a. Este dt es Admin. Entonces este es el beneficio de encapsular esta lógica dentro del objeto de usuario Entonces hay un solo lugar que necesitamos modificar. Anteriormente, teníamos esto en dos lugares diferentes. Y con este cambio de símbolo, tuvimos que recordar aplicar este cambio en dos lugares diferentes en el código. Entonces esta es nuestra ficha de rodilla. Ahora en el servidor, necesitamos una nueva función de middleware para verificar si el usuario actual es administrador o Entonces aquí en la carpeta middleware, voy a agregar un nuevo archivo, admin Entonces aquí establecemos el módulo que exporta a una función de middleware Y toma una solicitud, una respuesta y una referencia a la siguiente función de middleware en la canalización de procesamiento de solicitudes Entonces aquí estamos asumiendo que esta función de middleware se ejecutará después de nuestra función se ejecutará después de middleware de autorización Así que nuestros conjuntos de funciones de middleware de autorización solicitan no usuario, por lo que podemos acceder a eso en esta Entonces solicito a ese usuario que sea admin, o digamos que si no están en admin, vamos a devolver el estado de respuesta. Establecemos el estado 24 oh tres, lo cual está prohibido. Esta es una de las áreas en las que muchos desarrolladores se equivocan. Entonces tenemos 41, lo que significa no autorizado, y tenemos cuatro oh tres, lo que significa prohibido. Usamos no autorizado cuando el usuario intenta acceder a un recurso protegido, pero no suministra un JSN WebTKEN válido Entonces les damos la oportunidad de reintentar y enviar un JCN WebTKEN válido ahora si envían un token web GSN válido y todavía no se les permite acceder al recurso de destino, ahí es cuando usamos cuatro oh tres, lo que significa prohibido, lo que significa que no lo intentes de nuevo, simplemente no podemos Así que de vuelta aquí, establecemos el estado y enviamos un mensaje como acceso denegado. Ahora, de lo contrario, si el usuario es admin, pasamos el control a la siguiente función de middleware, que es, en este caso, el manejador de ruta Ahora vamos a aplicar esta función de ware intermedio en una de nuestras rutas. Así que volvamos a las empresas punto JS, veamos el método delete. Entonces, aquí está nuestro método de eliminación. Aquí queremos aplicar dos funciones de middleware. Así que tenemos que pasar array. El primero es OT y el segundo es admin. Por lo que estas funciones de middleware ejecutarán en secuencia Primero arte si el cliente envía un Jas variado en webtken y luego llegaremos a la segunda función milware El usuario es un administrador, entonces se ejecutará la tercera función de middleware o manejador de ruta Ahora, tenemos que importar esto en el TA. Tan constante admin, configuramos esto para que requiera ir a la carpeta middleware y cargar el módulo admin Ahora, vamos a probar esto. De vuelta en Cartero. Voy a abrir una nueva pestaña y enviar una solicitud de eliminación a este endpoint, host local STDP para 3,000 empresas API Ahora déjeme tomar una identificación para una empresa de la base de datos de Mongo IV Así que ve a Companies Collection, aquí, copia este ID y ponlo en nuestro endpoint así. No olvides incluir el token de probabilidades. De lo contrario, obtendrá el error de autorización. Exceso denegado, ningún token lo proporciona. Entonces vamos a poner el token y ahora mandar esto. Hermoso. Tenemos una respuesta de 200, y aquí está la compañía que fue eliminada.