‫Jonas: Sigamos ahora escribiendo nuestra función
‫de protección de middleware.
‫Entonces, en la última lección, leímos
‫el token del encabezado de
‫autorización y luego verificamos si el token realmente existe.
‫Así que aquí mismo.
‫Y a continuación, tenemos el paso de verificación del token.
‫Y espero que recuerden que
‫en este paso verificamos si alguien manipuló
‫los datos o también si el token ya caducó.
‫Así que ya usamos, desde el paquete de token web JSON, la función
‫de asignación de
‫función, y ahora usaremos la función de verificación.
‫Así que al igual que antes, jwt. Verifique, y luego
‫allí, como puede imaginar, pasamos el token para que el algoritmo
‫pueda leer la carga útil y luego
‫recordar que este paso también necesita el secreto.
‫Básicamente, para crear la firma de prueba.
‫Entonces ese secreto es el proceso. env. JWT_SECRET.
‫¿Recuérdalo?
‫Ahora, como tercer
‫argumento, esta función realmente requiere una función de devolución de llamada.
‫Entonces, esta devolución de llamada se
‫ejecutará tan pronto como se complete la verificación.
‫Entonces ve que esta verificación
‫aquí es en realidad una función asincrónica.
‫Entonces verificará un token, y luego, cuando esté
‫listo, llamará
‫a la función de devolución de llamada que podamos especificar.
‫Ahora, hemos estado trabajando con promesas todo
‫el tiempo, y realmente no quiero romper ese patrón aquí.
‫Y entonces, realmente vamos a prometer esta función.
‫Básicamente, hacer que devuelva una promesa.
‫Y de esa manera, podemos usar async
‫await como cualquier otra función async que hemos estado usando.
‫Entonces, para hacer
‫eso, Node en realidad tiene una función promisify incorporada.
‫Todo lo que necesitamos hacer para
‫usarlo es requerir el módulo util incorporado.
‫Así que hagámoslo desde arriba, en realidad.
‫Entonces eso creará un objeto llamado util, require ...
‫Muy bien, eso significa utilidad.
‫Eso no es lo que quería.
‫Eso significa utilidad.
‫Y luego, vamos a utilizar el método promisify.
‫Pero como solo usaremos ese método, podemos
‫hacerlo más fácilmente.
‫Entonces, en lugar
‫de hacer esto, simplemente podemos desestructurar ese objeto y
‫tomar promisificar directamente desde allí.
‫Entonces, nuevamente, esto solo está usando la desestructuración de ES6.
‫Bien, ahora es muy fácil de usar.
‫Todo lo que tenemos que hacer es realmente llamar a promisificar.
‫Así que promisifique y luego pase la función allí.
‫Y ahora, todo esto aquí es una función
‫que debemos
‫llamar, que luego devolverá una promesa.
‫Entonces aquí, en realidad llamamos a la función.
‫Y esto devolverá una promesa,
‫por lo que podemos esperarlo y almacenar el resultado en una variable.
‫Entonces, el valor de resultado de la
‫promesa será en realidad los datos
‫decodificados, por lo que la carga útil decodificada de este token web JSON.
‫Así que déjame llamarlo decodificado aquí.
‫Está bien.
‫Y podemos esperar porque ya dijimos que
‫es una función asincrónica.
‫Y ahora, solo para ver que realmente
‫funciona, registremos también estos datos decodificados en la consola.
‫Y de hecho, podemos eliminar esta consola. cerrar sesión en el token.
‫Ese que ya no necesitamos.
‫Intentemos enviar esta solicitud nuevamente, y sí, pero esta vez
‫activando este encabezado de autorización para
‫que enviemos un token web JSON junto con la solicitud.
‫Entonces eso lo envió.
‫Y ahora, de hecho, tenemos acceso a los
‫datos y, por lo tanto, ahora tenemos acceso a la ruta protegida.
‫¿Okey?
‫Pero lo que quería ver es este objeto decodificado aquí.
‫Y entonces este debería ser el ID de usuario.
‫Así que echemos un vistazo a eso en Postman nuevamente.
‫Entonces 62a42.
‫Y entonces, de hecho, bueno, ¿dónde tenemos eso?
‫Echemos un vistazo a Compass.
‫Y de hecho, el ID de este usuario es 62a42.
‫Y eso significa que realmente tenemos
‫nuestra carga útil correcta aquí.
‫Básicamente, la identificación de usuario correcta.
‫Luego, también tenemos la marca de tiempo de la fecha
‫de creación y de la fecha de vencimiento del token.
‫Entonces esto está funcionando.
‫Pero ahora intentemos manipular la carga útil de
‫este token.
‫Copiemos aquí de nuevo.
‫Pero luego voy al depurador de JWT.
‫Así que de nuevo, en jwt. io.
‫Así que quitemos esto.
‫Y ahora lo que voy a hacer es cambiar algunos
‫datos aquí y luego cambiará el token codificado aquí, que luego
‫puedo seguir adelante y copiar.
‫Así que simplemente reemplacemos, en
‫realidad, solo reemplazaré estos dos números aquí
‫con algo diferente.
‫Y así, como ves, esto cambió la ficha aquí.
‫Y ahora, intentaré obtener acceso a
‫esa ruta
‫protegida utilizando este token web JSON manipulado.
‫Vale, ¿tiene sentido?
‫Así que solo para ver si funciona correctamente.
‫Así que estoy
‫copiando este aquí ahora y pegando este otro diferente.
‫Entonces, si ahora envío esta solicitud, obtenemos un error.
‫Que bien.
‫Entonces, vemos que el nombre del error es
‫JsonWebTokenError y tenemos una firma no válida.
‫Que bien.
‫Eso es exactamente lo que estábamos buscando.
‫Entonces ese es uno de los dos errores que pueden ocurrir.
‫El otro es que el token ya ha caducado.
‫Este se llama JsonWebTokenError y, en
‫realidad, sigamos adelante y manejemos este error ahora.
‫Y la forma
‫en que podríamos hacerlo es agregando un bloque try-catch aquí.
‫¿Derecha?
‫Entonces, justo después de hacer este
‫código, podríamos introducir un bloque
‫de prueba, y luego en la captura, crearíamos
‫errores que se enviarían al cliente.
‫Ahora, en lugar de hacerlo de
‫esa manera, en realidad quiero usar nuestro middleware global de
‫manejo de errores para hacer eso por nosotros.
‫Así que no nos gusta hacer el manejo de errores aquí mismo
‫en nuestra función de middleware.
‫En cambio, generalmente lo delegamos al controlador de errores.
‫Entonces, hagamos exactamente lo mismo aquí.
‫Entonces controlador de errores.
‫Y luego es exactamente lo
‫mismo que tenemos con nuestros otros errores aquí.
‫Entonces, por ejemplo, el error de validación proviene de Mongoose, es
‫decir, de otra biblioteca.
‫Y ahora, este error en realidad proviene de otra
‫biblioteca y también tiene su propio nombre.
‫Así que consigamos eso.
‫Y es JsonWebTokenError.
‫Está bien.
‫Entonces, hagamos algo muy similar aquí.
‫Así que si. nombre es
‫este, entonces el error debe ser igual para manejar el error.
‫Bueno.
‫Así que sigamos
‫adelante y creemos esta función, de hecho, en algún lugar de aquí.
‫Y este es realmente extremadamente simple.
‫Todo lo que hace es tomar un error
‫y luego devolver un nuevo AppError.
‫¿Okey?
‫Entonces, en
‫esta función de flecha de ES6, como espero que sepa, podemos escribir estas frases
‫ingeniosas en las que ni siquiera tenemos
‫que especificar las llaves y tampoco la palabra clave return.
‫Así que esto devolverá
‫automática e implícitamente todo lo que pongamos aquí.
‫¿Derecha?
‫Entonces,
‫lo que queremos decir aquí es simplemente, token
‫inválido, inicie sesión nuevamente.
‫Y luego, el código de error, como antes,
‫es un 401 para No autorizado.
‫Ahora, esto solo funciona, recuerde, en producción.
‫Entonces, si hiciéramos esto ahora de
‫nuevo, obtendríamos exactamente lo mismo.
‫Entonces, regresemos aquí y ejecutemos
‫esto en producción.
‫Entonces npm run start: production.
‫Sí, así como así.
‫Entonces, si intentamos
‫esto ahora nuevamente, veamos si obtenemos nuestro error.
‫Y de hecho, lo hacemos.
‫Entonces, si, en este momento, un usuario en
‫producción intenta acceder a nuestra aplicación con
‫un token no válido, entonces solo recibe este mensaje de error.
‫¿Está bien?
‫Entonces ese es el primer error que podemos obtener.
‫Pero otro es que el usuario intenta acceder
‫a la aplicación
‫con un token ya caducado.
‫Entonces, ahora intentemos crear ese error.
‫Y para hacer eso, cambiaré
‫el tiempo que tarda el token en caducar.
‫Entonces, ahora mismo, tenemos 90 días.
‫Digámoslo como cinco segundos.
‫Bueno.
‫Dale una oportunidad.
‫Y ahora intente iniciar sesión nuevamente.
‫Así que guardemos este aquí también.
‫Entonces, en usuarios, y luego inicie sesión.
‫Entonces podemos iniciar sesión y luego nos dará un nuevo token,
‫pero este token solo es válido por cinco segundos.
‫Y entonces, estos cinco segundos deberían haber pasado en este punto.
‫Así que ahora copiaré este token e intentaré acceder a
‫nuestra ruta protegida usando ese token.
‫Así que pégalo aquí.
‫Y ahora, veamos qué obtenemos.
‫Y de hecho, por alguna razón, funcionó.
‫Así que echemos un vistazo a nuestro depurador JWT nuevamente.
‫Y dice, creado el 2 de mayo, pero vence
‫solo el 31 de julio.
‫Entonces, algo salió mal en esa creación simbólica, supongo.
‫Entonces, cambiemos esto aquí nuevamente.
‫Y solo voy a poner cinco aquí.
‫Y entonces, cinco deberían
‫permanecer durante cinco milisegundos, o incluso puedo poner
‫5000, que deberían ser cinco segundos.
‫Bueno.
‫Así que déjame guardarlo ahora de nuevo para reiniciar el servidor.
‫Pruébalo otra vez.
‫Así que inicie sesión de nuevo aquí.
‫Está bien.
‫Así que ahora todo
‫lo que tenemos que hacer es básicamente esperar cinco segundos, y ese tiempo ya debería haber pasado en este punto.
‫Pégalo aquí de nuevo.
‫Y vamos.
‫Y de hecho, obtenemos un error.
‫Ahora recuerde cómo este es
‫básicamente el error estándar que obtenemos en caso de que no
‫manejemos correctamente ese error en nuestro manejo de errores.
‫¿Derecha?
‫Así que echemos un vistazo al error.
‫Y de hecho, lo tenemos aquí en la consola.
‫Veamos de dónde viene eso.
‫Y sí, viene de este lugar.
‫Entonces este es el caso en el que tenemos un error desconocido.
‫Recuerde, entonces es un error que no está marcado como
‫un error operativo y, por lo
‫tanto, queremos registrarlo.
‫Así que lo registramos aquí y
‫luego enviamos este mensaje
‫de error genérico al cliente, el que acabamos de
‫ver en Postman.
‫Pero aquí tenemos los detalles de este error.
‫Y entonces, este tiene el nombre de TokenExpiredError.
‫Está bien.
‫Entonces, ahora manejemos este también.
‫Así que lo estoy copiando ahora y luego
‫creo otro si aquí.
‫Entonces, si el error. nombre es igual a este, bueno,
‫entonces, digamos, manejeJWTExpiredError
‫con
‫la flecha.
‫Copiemos y pongámoslo aquí.
‫Y esto, por supuesto, es muy similar al anterior.
‫Tu token ha caducado.
‫Inicie sesión de nuevo.
‫Y nuevamente, con un código de error 401.
‫Bien, intentémoslo de nuevo.
‫Y ese es exactamente el mensaje de
‫error que ahora deberíamos ver aquí.
‫Está bien.
‫Y de hecho lo es.
‫Excelente.
‫Terminemos el proceso aquí
‫e iniciemos en modo de desarrollo, por supuesto.
‫Entonces npm
‫comienza, y está bien.
‫Así que este, no necesitamos más, así que cerrándolo.
‫O en realidad, solucionemos este pequeño error aquí, porque de hecho,
‫no usamos este error aquí en absoluto.
‫Así que deshagámonos de eso.
‫Y luego aquí abajo, no necesitamos pasarlo allí.
‫Frio.
‫Por supuesto, también debemos volver a cambiar esto a 90 días.
‫Está bien.
‫Entonces,
‫para estar realmente seguros, inicie sesión aquí nuevamente,
‫copiemos el
‫token y colóquelo aquí.
‫Ahora, este proceso aquí de copiar el
‫token y luego pegarlo aquí en este encabezado puede
‫parecer un poco extraño, y de hecho lo
‫arreglaremos en uno
‫de los videos futuros para
‫que, básicamente, este proceso ocurra automáticamente.
‫Pero ahora, lo importante es que en realidad
‫ha vuelto a funcionar ahora.
‫Entonces podemos deshacernos de esta consola. inicie sesión aquí y continúe con
‫el siguiente paso.
‫Y podríamos detenernos aquí ahora si quisiéramos.
‫Y de nuevo, la mayoría de los
‫tutoriales que encontrarás allí, de hecho, se detendrían aquí.
‫Pero esto todavía no es lo suficientemente seguro.
‫Entonces, por ejemplo, ¿qué pasa si el usuario
‫ha sido eliminado mientras tanto?
‫Entonces, el token seguirá existiendo, pero si el
‫usuario ya no existe, entonces
‫en realidad no queremos iniciar sesión, ¿verdad?
‫O peor aún, ¿qué pasa si el usuario realmente ha
‫cambiado su contraseña después de que
‫se haya emitido el token?
‫Bueno, eso tampoco debería funcionar, ¿verdad?
‫Por ejemplo, imagine que alguien
‫robó el token web JSON de un usuario.
‫Pero luego, para
‫protegerse contra eso, el usuario cambia su contraseña.
‫Y así, por supuesto, ese token antiguo que se
‫emitió antes del cambio de contraseña ya no debería ser válido.
‫Por lo que no debe aceptarse el acceso a rutas protegidas.
‫Entonces, ese es el tipo de cosas que implementaremos aquí en
‫el paso tres y el paso cuatro.
‫Entonces, lo primero que debe hacer es verificar si el
‫usuario todavía existe.
‫Y entonces, ese debería ser el más fácil.
‫Así que digamos, Usuario. findById.
‫Entonces, esta es la razón por la
‫que ahora tenemos la ID en
‫la carga útil, porque ahora podemos usar esa
‫ID y consultar al usuario usando solo esa ID.
‫Tan decodificado. identificación.
‫¿Está bien?
‫Entonces eso debería encontrar al nuevo usuario.
‫Y, por supuesto, debemos esperar eso y
‫luego almacenarlo en una variable.
‫Lo llamo freshUser.
‫¿Está bien?
‫Porque no es realmente un usuario nuevo.
‫Eso es solo cuando creamos uno.
‫Pero esto no es realmente nuevo, en realidad es
‫solo el usuario basado en la ID decodificada.
‫¿Okey?
‫Y podemos
‫hacer esto para que podamos estar 100% seguros de que
‫la identificación es realmente correcta, porque si lo
‫hicimos hasta este punto del código aquí, entonces eso significa que el
‫proceso de verificación que tenemos anteriormente, aquí, fue exitoso.
‫De lo contrario, esto habría provocado un error
‫que habría impedido que la
‫función continuara.
‫Y entonces, nuevamente, este proceso
‫de verificación aquí está a cargo de la verificación si
‫nadie alteró la identificación que está
‫en la carga útil de este token.
‫Y así, debido a eso, podemos
‫estar 100% seguros de que el usuario para el que
‫hemos emitido el JWT es exactamente aquel cuyo ID está ahora dentro
‫de la carga útil decodificada, entonces este.
‫¿Okey?
‫Entonces, el proceso de verificación es realmente clave.
‫Es realmente lo que hace que todo esto funcione.
‫De todos modos, ahora lo que tenemos que hacer es
‫comprobar si realmente hay un nuevo usuario.
‫Y si no, bueno, claro, vamos a
‫devolver un nuevo error.
‫Entonces, si no hay freshUser,
‫regrese de este middleware y llame al
‫siguiente con un error.
‫Entonces, este es un patrón que hemos estado
‫viendo una y otra vez en este punto, ¿verdad?
‫Entonces el token ya no
‫existe.
‫Y de hecho, es al revés.
‫Entonces, en realidad, el usuario
‫que pertenece al token ya no existe.
‫¿Derecha?
‫Y luego, el 401.
‫Bueno.
‫Así que probemos esto una vez más.
‫Y de hecho creemos un nuevo usuario para eso.
‫Así que prueba con la misma contraseña para que siempre
‫usemos la misma aquí solo para hacer nuestras
‫pruebas un poco más fáciles.
‫Y sé que todas estas pruebas aquí hacen
‫que el video tome bastante tiempo,
‫pero por supuesto, es muy importante que probemos todo lo que
‫hacemos, especialmente en
‫un tema tan importante como la autenticación.
‫Así que ahora estoy usando este JWT aquí, así que
‫lo pego aquí, pero por supuesto, antes de enviar la solicitud, continuaré
‫y eliminaré ese usuario de inmediato.
‫¿Okey?
‫De nuevo, supongamos que
‫alguien creó un usuario y luego inició sesión,
‫y digamos, luego de un tiempo, el usuario fue eliminado.
‫Pero mientras tanto, alguien podría haber obtenido acceso a ese
‫JWT
‫y ahora podría intentar iniciar sesión como ese
‫usuario que, de hecho, ya fue eliminado.
‫Y entonces, nuevamente, no debemos permitir que eso suceda.
‫Permítanme eliminar este usuario aquí ahora.
‫Y ahí vamos.
‫Entonces, probémoslo ahora.
‫Y nuevamente, tenga en cuenta que el
‫usuario que pertenece al ID que está en esta carga útil ya no está allí.
‫Así que veamos.
‫Y, de hecho, recibimos este mensaje de error que acabamos de crear.
‫Entonces ese también está funcionando.
‫Y vayamos al último.
‫Entonces, paso número cuatro, verifique si el usuario
‫ha cambiado recientemente su contraseña.
‫Básicamente, después de que se emitió el token.
‫Y para implementar esta prueba, crearemos otro
‫método de instancia.
‫Básicamente, un método que
‫estará disponible en todos los documentos.
‫Entonces, los documentos son instancias de un modelo.
‫¿Está bien?
‫Y hacemos esto
‫porque es bastante código lo que necesitamos para esta verificación.
‫Entonces, en realidad, este código
‫pertenece al modelo de usuario y no al controlador.
‫¿Okey?
‫Entonces, hagámoslo
‫como lo hicimos antes para verificar la contraseña.
‫Entonces, en el modelo de usuario,
‫ya implementamos este método de instancia estática correctPassword, ¿recuerdas?
‫Y entonces, ahora creemos otro.
‫Entonces userSchema. métodos. changePasswordAfter.
‫Así que funciona, y en
‫esta función, pasaremos la marca de tiempo JWT.
‫Básicamente, esa marca de tiempo que dice cuándo
‫se emitió el token.
‫Así que llamemos a eso JWTTimestamp.
‫Está bien.
‫Y de forma predeterminada, devolveremos falso de este método.
‫Y eso significará que el usuario no ha cambiado
‫su contraseña
‫después de que se emitió el token.
‫¿Okey?
‫Pongamos eso aquí, devuelva falso, básicamente por defecto.
‫Bueno.
‫Pero también
‫tenemos if this, y recordemos que en un método de instancia, la
‫palabra clave this siempre apunta al documento actual.
‫Y entonces, aquí tenemos acceso a las propiedades.
‫Ahora, en realidad, necesitamos crear un campo ahora en nuestro esquema para
‫la fecha en la que se cambió la contraseña.
‫Entonces no tenemos eso todavía.
‫Así que agregémoslo rápidamente aquí.
‫Entonces passwordChangedAt, y el tipo
‫será una Fecha.
‫Ahora, esta propiedad passwordChangedAt aquí siempre
‫se cambiará, por supuesto, cuando alguien
‫cambie la contraseña.
‫Entonces, en este momento, no tenemos esa lógica en ningún lado, por
‫lo que en ningún lugar estamos definiendo esta propiedad.
‫Entonces, la mayoría de los documentos, la mayoría
‫de los usuarios, simplemente no tendrán esta propiedad en
‫sus datos, por lo tanto, en su objeto, ¿verdad?
‫Y entonces, por supuesto, tenemos que probar eso.
‫¿Okey?
‫Entonces, si existe
‫la propiedad passwordChangedAt, solo entonces queremos hacer la comparación.
‫¿Okey?
‫Pero si
‫no es así, si passwordChanged no existe, bueno, eso significa que el usuario
‫nunca ha cambiado la contraseña
‫y, por lo tanto, podemos simplemente devolver false.
‫Nuevamente, ese es nuestro valor predeterminado, lo que significa
‫que el usuario no ha cambiado
‫la contraseña después de esta marca de tiempo.
‫Bueno.
‫Y
‫ahora, para empezar, iniciemos sesión en la consola. passwordChangedAt, y por supuesto, el JWTTimestamp también, solo para
‫que
‫podamos ver cómo podemos compararlos.
‫Está bien.
‫Y ahora necesitamos
‫crear un usuario que tenga esta propiedad, ¿de acuerdo?
‫Y nuevamente, más adelante en la sección, cuando
‫implementaremos la lógica para
‫cambiar la contraseña, es cuando estableceremos esta propiedad.
‫¿Okey?
‫Pero ahora
‫lo configuraremos artificialmente, básicamente, aquí cuando creemos un nuevo usuario.
‫¿Okey?
‫Pongamos eso aquí.
‫Y aquí, cualquier fecha, de hecho, servirá.
‫Digamos que el 30 de abril de 2019 aquí.
‫Y entonces eso debería ser analizado en MongoDB sin problemas.
‫Probemos eso, veamos si funciona.
‫Y eso no funcionó.
‫Entonces realmente no pudo analizar la fecha, digamos.
‫Y de hecho, necesito comenzar con el año
‫y luego el día al final.
‫Entonces 2019 y luego 30 de abril.
‫Inténtelo de nuevo.
‫Y entonces ves que ahora realmente está funcionando.
‫Entonces tenemos esta fecha analizada aquí.
‫¿Okey?
‫Ahora, para ver realmente
‫el resultado de esto, por supuesto, necesitamos llamar a este método.
‫¿Okey?
‫Así que eso es lo que haremos aquí en el paso cuatro.
‫¿Okey?
‫Y entonces, recuerde
‫que podemos llamar a este método de instancia en un documento de usuario.
‫Tan freshUser. changePasswordAfter, y luego esa
‫marca de tiempo.
‫Entonces eso es decodificado. iat, por lo que se emitió en, básicamente.
‫Está bien.
‫Así que veamos simplemente el resultado de hacer eso.
‫Y entonces, por supuesto, esto debería ahora, no
‫aquí, por lo que debería registrar estos dos valores en la consola.
‫Bueno.
‫Ahora, por supuesto,
‫necesito iniciar sesión exactamente con este usuario, así que con la prueba,
‫así que aquí vamos.
‫Iniciar sesión.
‫Copie este token aquí nuevamente.
‫Y nuevamente, básicamente vamos a automatizar
‫eso en el próximo video, de hecho.
‫Bueno.
‫Pégalo aquí.
‫Y ahora, tenemos este error aquí.
‫Así que escribí mal el nombre de esta función aquí.
‫Bueno, copiémoslo.
‫Pruébalo otra vez.
‫Oh hombre.
‫¿Qué va mal ahora?
‫Y veo que simplemente olvidé este registro aquí.
‫Entonces otro error estúpido.
‫Probablemente lo vio venir.
‫Pero ahora aquí vamos.
‫Así que todo
‫funcionó bien, y todo lo que
‫realmente queríamos ver por ahora eran estos dos resultados.
‫Así que básicamente tenemos este aquí en este
‫formato de fecha, y luego el otro en esta marca de tiempo de milisegundos
‫o segundos aquí.
‫Y entonces, ahora necesitamos convertir este passwordChangedAt
‫también en una marca de tiempo como esa.
‫¿Está bien?
‫Y entonces, para eso, creemos una nueva variable.
‫Así que cambió la marca de tiempo.
‫Y podemos usar esto. passwordChangedAt. consigue tiempo.
‫¿Okey?
‫Y esa
‫es una de las muchas funciones de fecha que nos brinda JavaScript.
‫Está bien.
‫Y ahora, comparemos rápidamente
‫estos dos porque, en realidad, aún no estamos listos.
‫Así que enviándolo solo para ver los resultados aquí.
‫Entonces, lo que vemos aquí básicamente es que
‫este aquí es
‫ahora, básicamente, en segundos, y este en milisegundos.
‫Entonces es 1000 veces más.
‫Entonces, sabemos que necesitamos dividir esto entre
‫1000 y luego analizar todo esto como un número entero.
‫Y para eso usamos parseInt.
‫Entonces, otra función de JavaScript que está disponible para números.
‫Y luego también necesitamos especificar la base.
‫Así que este es un número de base 10.
‫¿Está bien?
‫Y ahora, de nuevo, veamos el resultado.
‫Y ahora, eso parece mucho más amigable.
‫Bueno.
‫Entonces, ahora devolvamos nuestro resultado.
‫Y nuevamente, tenga en cuenta que los medios falsos no cambian.
‫¿Okey?
‫Y no cambiado
‫básicamente significa que el día o la hora en que se emitió el token es menor
‫que la marca de tiempo modificada.
‫¿Okey?
‫Entonces, solo como un ejemplo
‫aquí, digamos que el token se emitió en el momento 100.
‫Pero luego, cambiamos la contraseña, digamos, en el momento 200.
‫¿Okey?
‫Entonces, cambiamos la
‫contraseña después de que se emitió
‫el token y, por lo tanto, esto ahora es cierto.
‫¿Está bien?
‫Y eso es exactamente lo que queremos volver
‫aquí, porque falso significa que no ha
‫cambiado y, por tanto, verdadero, por supuesto, significa que ha cambiado.
‫Y eso es exactamente lo que tenemos aquí.
‫Pero ahora, digamos que la contraseña se cambió
‫por última vez
‫en 200, pero solo después de eso,
‫emitimos el token, digamos, en el momento 300.
‫¿Y entonces, 300, menos de 200?
‫No, eso es falso.
‫Y entonces, devolvemos falso, lo que nuevamente significa que no ha cambiado.
‫Y por eso usamos este signo menos aquí.
‫¿Okey?
‫Regresemos a nuestro controlador y realmente usemos esto.
‫Entonces, si realmente se cambió la contraseña, bueno,
‫en este caso, realmente queremos un error.
‫Entonces regrese a continuación, nuevamente, un nuevo AppError.
‫Recientemente...
‫Inicie sesión de nuevo.
‫Bueno.
‫Y una vez más, código 401.
‫Está bien.
‫Nuevamente, esto volverá
‫a ser verdadero si el usuario realmente cambió su contraseña.
‫Y entonces, si todo esto aquí es cierto,
‫bueno, entonces exactamente en ese caso es cuando
‫queremos que suceda este error.
‫¿Está bien?
‫Así que ese fue en realidad el último paso.
‫Bueno.
‫Entonces, básicamente, si el código puede llegar hasta
‫el final de este código aquí, solo entonces, se ejecutará el siguiente.
‫Y luego, con el siguiente, pasamos al siguiente controlador
‫de ruta, lo que significa efectivamente otorgar acceso
‫a esa ruta protegida.
‫De hecho, pongamos eso aquí.
‫Otorgar acceso a ruta protegida.
‫¿Okey?
‫Porque eso es realmente todo lo que hace lo siguiente.
‫A continuación, nos lleva al siguiente
‫middleware, que suele ser, entonces, el propio controlador de ruta, por
‫lo que es el que devuelve los datos que estaban protegidos.
‫Bueno.
‫Solo una última
‫cosa que queremos hacer aquí es poner todos los datos del usuario en la solicitud.
‫Entonces, simplemente podemos decir, req, entonces solicitar,. usuario será igual a
‫freshUser.
‫Bueno.
‫Y nuevamente, por
‫supuesto, el código solo llega
‫a este punto aquí en caso de que todo sea correcto.
‫¿Okey?
‫Entonces, esto aquí
‫podría ser útil en algún momento en el futuro.
‫Excelente.
‫Probemos esto una vez más.
‫Y básicamente, este cambio ya es pasado.
‫Y entonces, este token que tenemos aquí, o en realidad,
‫podría haber reutilizado
‫solo este en lugar de registrarlo nuevamente.
‫Pero de todos modos, este token
‫se emitió después de que se cambiara la contraseña.
‫Y entonces, este token ahora debería funcionar.
‫Así que inicie sesión de
‫nuevo e intentemos con este token.
‫Y de hecho, tenemos acceso.
‫Ahora, moviéndonos a Compass para cambiar esa fecha.
‫Bueno.
‫Digámoslo un mes después.
‫Y entonces, eso será en
‫el futuro, al menos, en mi futuro cuando esté grabando este video.
‫Por supuesto, lo hará en un momento posterior.
‫Entonces, para probar esto, por favor ponga esto en su futuro.
‫Entonces, en el futuro de la fecha en la que
‫estás viendo este video.
‫Entonces, si vuelvo
‫a Postman e inicio sesión nuevamente, está bien, entonces si inicio sesión nuevamente ahora
‫e intento acceder a esa ruta, bueno,
‫entonces este token se emitirá, básicamente,
‫después de que se haya cambiado la contraseña.
‫O incluso antes de que se haya cambiado la contraseña.
‫Entonces, perdón por esa confusión.
‫Entonces, la contraseña se cambió el 30 de
‫mayo, pero este token se emitió el 2 de mayo, y así, antes.
‫Básicamente, ahora es como si el usuario hubiera cambiado su contraseña después
‫de que se emitió el token.
‫Y esa es exactamente la situación en la que no queremos dar acceso
‫a la ruta protegida.
‫Y entonces, esto ahora debería reflejar eso.
‫Y, de hecho, el usuario cambió recientemente
‫la contraseña, inicie sesión nuevamente.
‫Excelente.
‫Entonces eso ahora funciona.
‫Así que nuestro middleware de protección ahora está completamente implementado.
‫Vamos a deshacernos de esta consola. inicie sesión aquí.
‫Ya no necesito ese.
‫Y esta bien.
‫Así que recapitulemos rápidamente, y este video
‫se está ejecutando muy
‫largo, un poco más de lo que esperaba.
‫Pero es realmente
‫importante comprender y explicar cómo funciona
‫todo esto y por qué es importante.
‫Entonces, prefiero eso a hacer este video mucho más corto.
‫Por supuesto, podría simplemente escribir el código, pero entonces no entenderías realmente lo
‫que está pasando.
‫Entonces esta parte ya la entendimos.
‫Luego, en esta parte, también creo,
‫así que aquí es donde ocurre la verificación,
‫básicamente para ver si la carga útil del
‫token no ha sido manipulada por algún tercero malicioso.
‫¿Okey?
‫Y dado que
‫llegamos a este código aquí, significa que nadie cambió
‫el token web JSON y, por lo tanto, podemos obtener un usuario nuevo.
‫Básicamente, podemos obtener el usuario
‫actual, llamémoslo currentUser.
‫¿Por qué no?
‫Entonces aquí, aquí y también aquí.
‫¿Okey?
‫Entonces podemos obtener el
‫usuario actual de esa ID que se acaba de decodificar de la carga útil.
‫Ahora, si el currentUser no existe, entonces
‫esto es lo que estamos probando aquí,
‫bueno, entonces en ese caso no queremos dar acceso
‫a la ruta,
‫y en su lugar crear este nuevo error.
‫Pero si el usuario existe, bueno,
‫llegamos al punto número
‫cuatro, donde luego verificamos si ha ocurrido un cambio de
‫contraseña después de que se emitió el token, ¿verdad?
‫Y si lo hizo, de nuevo, creamos un nuevo error.
‫Y si no fue así, entonces llegamos hasta
‫el final de
‫la función de middleware, donde
‫luego asignamos el currentUser a solicitar. user para que podamos usarlo en
‫una siguiente función de middleware.
‫¿Okey?
‫Porque recuerda,
‫este objeto de solicitud, este es el que
‫viaja, básicamente, de middleware a middleware.
‫Entonces, si queremos pasar datos de
‫un middleware al siguiente, simplemente
‫podemos poner algunas cosas en el objeto de
‫solicitud, y luego esos datos estarán disponibles en un momento posterior.
‫Está bien.
‫Eso es todo.
‫Este es
‫un algoritmo de protección de rutas
‫muy sofisticado y muy completo, básicamente, pero creo que es realmente importante hacerlo
‫lo mejor que podamos.
‫De todos modos, me alegro de ver que llegaste
‫al final de este gran video, y
‫te veré en el siguiente.