No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

18 Días
17 Hrs
41 Min
20 Seg

Protección de rutas

11/20
Recursos

Aportes 17

Preguntas 7

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

wow! excelentes cursos de Nicolás Molina toda la parte de node con Express y base de datos con postgres y todas las librerías para autentificación , seguridad de lo mejor felicidades , ahora ya puedo utilizar node en mi trabajo. :)

Encontré una forma para proteger todas las rutas de /categories sin agregar el middleware en cada uno de los métodos.

router.use('/categories', passport.authenticate('jwt', { session: false }), categoriesRouter);

Para proteger las rutas se instala la estrategia passport-jwt, esta estrategia va a capturar el token que viene del header, si el token está firmado con nuestra firma entonces lo va a autorizar, de otro modo no tendrá acceso a la ruta.
Comando de instalación: npm install passport-jwt.


Se crea la nueva estrategia jwt.strategy.js:

Se requiere la Strategy y ExtractJwt (dónde el token está para que extraiga el token).

Se crean las options, estas contienen:

  • jwtFromRequest → Indica de dónde se saca el token, en este caso del header como bearer token
  • secretOrKey → Cuál es el secreto, necesario para poder verificar si la firma es válida o no.

La nueva estrategia (JwtStrategy) recibe las options y una función callback que recibe el payload del JWT y la función done que retorna el payload que ya verificó.

const { Strategy, ExtractJwt } = require('passport-jwt');
const { config } = require('../../../config/config');

const options = {
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
  secretOrKey: config.jwtSecret,
};

const JwtStrategy = new Strategy(options, (payload, done) => {
  return done(null, payload);
});

module.exports = JwtStrategy;

La nueva estrategia se agrega a utils/auth/index.js:

const passport = require('passport');

const LocalStrategy = require('./strategies/local.strategy');
const JwtStrategy = require('./strategies/jwt.strategy');

passport.use(LocalStrategy);
passport.use(JwtStrategy);

Implementando la nueva estrategia a la ruta para crear categorías será como decir “los clientes que tengan un JWT válido van a poder crear categorías”.

Se requiere passport, después se utiliza el método authenticate que recibe el nombre de la estrategia jwt sin un manejo de sesión (session: false).

categories.router.js:

const passport = require('passport');

router.post(
  '/',
  passport.authenticate('jwt', { session: false }),
  validatorHandler(createCategorySchema, 'body'),
  async (req, res, next) => {
    try {
      const body = req.body;
      const newCategory = await service.create(body);
      res.status(201).json(newCategory);
    } catch (error) {
      next(error);
    }
  }
);

En resumen, primero se identifica al usuario (passport.authenticate), después se validan los datos (validatorHandler) y si todo bien, se conecta a la capa de servicios para poder crear la categoría.

En Insomnia se envía el token a través de los headers o usando la opción Bearer de la pestaña Auth.

Un pequeño aporte para proteger rutas agrupadas por el recurso, sirve para ahorrar un poco de trabajo al no tener que ir al archivo de las rutas para proteger una por una.

const express = require('express');
const passport = require('passport');
const { checkRoles } = require('./../middlewares/auth.handler');

const usersRouter = require('./users.router');
const profilesRouter = require('./profiles.router');
const coursesRouter = require('./courses.router');
const skillsRouter = require('./skills.router');
const authRouter = require('./auth.router');

function routerApi(app) {
  const router = express.Router();
  app.use('/api/v1', router);
  
  router.use(
    '/users', 
    passport.authenticate('jwt', {session: false}),
    checkRoles('admin'),
    usersRouter
  );
  
  router.use(
    '/profiles', 
    passport.authenticate('jwt', {session: false}),
    profilesRouter
  );
  
  router.use('/courses', coursesRouter);
  router.use('/skills', skillsRouter);
  router.use('/auth', authRouter);
}

module.exports = routerApi;

🔐 Clase #11: Protección de rutas 11/20 🔐

 

Cuando hacemos el login, el backend nos envía un token, ese token podemos usarlo para poder navegar diversas rutas, de modo que el backend nos solicita el token generado al hacer el login para acceder a la ruta protegida.

 

Pasos: 📝

 
- Vamos a la página de passport, en passport-jwt indica que se debe instalar el paquete en la terminal:
 

npm install passport-jwt

 
Cuando haya instalado bien al arrojar:
 

found 0 vulnerabilities

 

  • Vamos a VSC, dentro de la ruta utils/auth/strategies se crea el archivo jwt.strategy.js, el código queda:
     
//Llamar la librería passport-jwt
const { Strategy, ExtractJwt } = require('passport-jwt');
//Necesitamos a config para el secreto
const { config } = require('../../../config/config');

const options = {
  //De dónde va a sacar el token:
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
  //Secreto para ver si la firma es válida o no:
  secretOrKey: config.jwtSecret
}

//Estrategia:
const JwtStrategy = new Strategy(options, (payload, done) => {
  //Retorna cuando todo está bien y devuelve el payload que verificó:
  return done(null, payload);
});

module.exports = JwtStrategy;

 
Guardamos, abrimos el archivo index.js de la ruta utils/auth, agregamos la nueva estrategia creada de jwt, el código queda:
 

const passport = require('passport');
//Aqui se definen qué estrategias se van a usar
const LocalStrategy = require('./strategies/local.strategy');
const JwtStrategy = require('./strategies/jwt.strategy');

passport.use(LocalStrategy);
passport.use(JwtStrategy);

 
Guardamos, vamos a la carpeta categories y abrimos el archivo categories.routes.js, agregamos en la librería (en la cabecera) a passport:
 

const passport = require('passport');

 
Luego agregamos en la petición del POST la autenticación del jwt, el código queda:
 

router.post('/',
  //Proteger este endpoint con passport
  passport.authenticate('jwt', {session: false}),
  validatorHandler(createCategorySchema, 'body'),
  async (req, res, next) => {
    try {
      const body = req.body;
      const newCategory = await service.create(body);
      res.status(201).json(newCategory);
    } catch (error) {
      next(error);
    }
  }
);

 
Guardamos, si en la terminal no se ha compilado, ejecutar: npm run dev cuando salga Mi port 3000, podemos abrir Insomnia, vamos a la carpeta de Auth, en la petición del POST (login) y como tenemos en la salida el token, lo copiamos, vamos a la carpeta de Categories, luego a Create Category con la petición POST y la dirección:
 
_. API_URL/api/v1/categories con la opción de desarrollador (dev), si no enviamos el token, en la salida tenemos un código 401 Unauthorized (que no estamos autorizados para acceder).
 
Como ya tenemos el token, hay una pestaña que dice “Auth”, le damos click y en la lista desplegable elegimos a “Bearer” y en la casilla donde sale TOKEN pegamos el token que copiamos de Auth cuando hicimos login, en el JSON en el body tenemos:
 

{
	"name": "new category",
	"image": "dirección página"
}

 
Al dar Send, obtenemos un código 201 Created:
 

{
	"createdAt": "2023-03-27T20:40:12.397Z",
	"id": 3,
	"name": "new category",
	"image": "dirección página"
}

 
Si seleccionamos la pestaña “Timeline” aparece el tipo de “Authorization” que en nuestro caso es de tipo “Bearer”:
 

 
Otra forma de enviar el token es que en “Header” antes de enviar la petición POST se coloque en la primera casilla: Authorization y en la segunda casilla: Bearer seguido del token:
 


 

En Insomnia, al igual que postman, se puede añdir una variable al entorno para no tener que estar metiendo el token a cada ruta.

  • Seleccionar la opción Manage Enviroments
  • Añadir una nueva variable con el valor access_control, pulsar control + espacio para que salga un menú contextual asociado al valor de esa variable, y escribir el texto response
  • Pulsar en el texto que se genera como resultado. Esto abrirá un popup donde se puede seleccionar en Requestla ruta del login y el filter añadir $.token. En el preview nos debería aparecer el token
  • Luego hay que ir a cada ruta y en la pestaña Auth, escoger Bearer y en el campo de introducción de Token añadir la vairable (control + barra espaciadora) y _access_token

BEARER[portador] AUTHENTICATION o autenticación de portador (también llamada autenticación de token) es un esquema de autenticación HTTP que implica tokens de seguridad llamados tokens de portador. El nombre “autenticación de portador” puede entenderse como “dar acceso al portador de este token”.

Guarde el

passport.authenticate('jwt', {session: false})

En una const para simplificar todo un poco y las fui agregando para proteger las demas routers

Reto hecho:

const express = require('express');
const passport = require('passport');

const CategoryService = require('./../services/category.service');
const validatorHandler = require('./../middlewares/validator.handler');
const { createCategorySchema, updateCategorySchema, getCategorySchema } = require('./../schemas/category.schema');

const router = express.Router();
const service = new CategoryService();

const protectRoute = passport.authenticate('jwt', { session: false });

router.get('/', async (req, res, next) => {
  try {
    const categories = await service.find();
    res.json(categories);
  } catch (error) {
    next(error);
  }
});

router.get('/:id',
  validatorHandler(getCategorySchema, 'params'),
  async (req, res, next) => {
    try {
      const { id } = req.params;
      const category = await service.findOne(id);
      res.json(category);
    } catch (error) {
      next(error);
    }
  }
);

router.post('/',
  protectRoute,
  validatorHandler(createCategorySchema, 'body'),
  async (req, res, next) => {
    try {
      const body = req.body;
      const newCategory = await service.create(body);
      res.status(201).json(newCategory);
    } catch (error) {
      next(error);
    }
  }
);

router.patch('/:id',
  protectRoute,
  validatorHandler(getCategorySchema, 'params'),
  validatorHandler(updateCategorySchema, 'body'),
  async (req, res, next) => {
    try {
      const { id } = req.params;
      const body = req.body;
      const category = await service.update(id, body);
      res.json(category);
    } catch (error) {
      next(error);
    }
  }
);

router.delete('/:id',
  protectRoute,
  validatorHandler(getCategorySchema, 'params'),
  async (req, res, next) => {
    try {
      const { id } = req.params;
      await service.delete(id);
      res.status(201).json({id});
    } catch (error) {
      next(error);
    }
  }
);

module.exports = router;

Por si quieren proteger todas las rutas excepto la de login

app.all(/^\/api\/v1\/(?!login).*$/, passport.authenticate('jwt', {session: false}))

Si alguien esta utilizando cookies para guardar el token, para que funcione la estrategia de passport-jwt deben usar cookieParser() en su servidor.

Aqui les dejo un ejemplo de la configuracio nen el index.js principal.

Como trabajan juntos Bueno sabemos que con\[\[Passport.js]] hicimos el login y con \[\[JWT]] sacamos el token , ahora el reto nace en como aplicar una verificacion de este token en nuestras rutas para ello haremos uso de la librería `````bash npm i passport-jwt ````` Esta librería nos proporciona un método `fromAuthHeaderAsBearerToken()`, que extrae el token del encabezado de la solicitud y verifica si se desencripta correctamente con nuestra clave secreta. Para empezarlo a usar debemos de : `````js // Llamos a Strategy y a la proiedad "ExtractJwt" const {Strategy, ExtractJwt} = require("passport-local") require("dotenv").config() const secret = process.env.JWT\_SECRET // Le inidcamos que vamos a extraer el token del header de nuestra solicitud y le pasamos el secret que creamos para los token const options = {   jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey : secret } // Luego como el passport local creamos una instancia de una nueva estrategia con tres parametros las opciones para que obtenga el token y lo verifique ademas del el payload y el done const JwtStrategy = new Strategy(options, (payload, done) =>{   return done(null , payload) }) module.exports = JwtStrategy ````` Para usarlo en la ruta al igual que con passport local solo demos indicar ````js // Antes indicabamos el local ahora para hacer referencia al jwt debmos ingresar el nombre  passport.authenticate("jwt", {session:false}), ````` Usamos `passport-jwt` debido a sus ventajas para trabajar con tokens. Al recibir el token desde el encabezado, podemos analizar y verificar su contenido de manera eficiente sin tener que crear toda la estructura de Bearer Token por nosotros mismos
## **Cómo trabajan juntos** Sabemos que con Passport manejamos el login y con JWT generamos el token. Ahora, el reto es cómo aplicar la verificación de este token en nuestras rutas. Para esto, usaremos la librería `passport-jwt`. ````` npm install passport-jwt ````` Esta librería nos proporciona un método `fromAuthHeaderAsBearerToken()`, que extrae el token del encabezado de la solicitud y verifica si se desencripta correctamente con nuestra clave secreta. Para empezarlo a usar ``````js // Llamos a Strategy y a la proiedad "ExtractJwt" const {Strategy, ExtractJwt} = require("passport-local") require("dotenv").config() const secret = process.env.JWT\_SECRET // Le inidcamos que vamos a extraer el token del header de nuestra solicitud y le pasamos el secret que creamos para los token const options = {   jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey : secret } // Luego como el passport local creamos una instancia de una nueva estrategia con tres parametros las opciones para que obtenga el token y lo verifique ademas del el payload y el done const JwtStrategy = new Strategy(options, (payload, done) =>{   return done(null , payload) }) module.exports = JwtStrategy ````` **Ventaja por que usar esta librería** Usamos `passport-jwt` debido a sus ventajas para trabajar con tokens. Al recibir el token desde el encabezado, podemos analizar y verificar su contenido de manera eficiente sin tener que crear toda la estructura de Bearer Token por nosotros mismos Además de ofrecer una manera rápida y sencilla de verificación con nuestro secret
Si se logra ver el contendido del token es porque tiene o conoce la clave secreta que se usó para generar el token, no sé si estoy en lo correcto, pero la aplicación ya estaría comprometida.
En mi caso para mi pequeño proyecto, al momento de verificar las credenciales del usuario envía una **cookie** la cual contiene el **token** **jwt**. **loginHandler.js**: ![](https://static.platzi.com/media/user_upload/cookie-ffe6f7fd-c967-4f5d-b3e4-0a2fa1bb66e7.jpg) decidí crear un **middleware,** el cual se encarga de verificar el token del usuario y gestionar el acceso a la ruta. **tokenHandler.js:** ![](https://static.platzi.com/media/user_upload/tokenHandler-2e5df6a0-ad8a-4637-bee9-aad1331dc63d.jpg) **createUserRouter.js**: ![](https://static.platzi.com/media/user_upload/router-bc999c43-a6b9-4f32-bf32-542f9b0b3115.jpg)

creacion de mi estrategia en el archivo archivo jwt.strategy.js

El vídeo tiene un error con el audio en el minuto 6.