Estoy intentando crear un middleware que pueda aceptar parámetros. ¿Cómo se puede hacer esto?
ejemplo
app.get('/hasToBeAdmin', HasRole('Admin'), function(req,res){
})
HasRole = function(role, req, res, next){
   if(role != user.role){
      res.redirect('/NotInRole);
   }
   next();
}

Respuestas:
function HasRole(role) { return function(req, res, next) { if (role !== req.user.role) res.redirect(...); else next(); } }También quiero asegurarme de no hacer varias copias de la misma función:
function HasRole(role) { return HasRole[role] || (HasRole[role] = function(req, res, next) { if (role !== req.user.role) res.redirect(...); else next(); }) }fuente
app.get('/a', hasRole('admin'))yapp.get('/b', hasRole('admin'))crearía un nuevo cierre para cada unohasRole. esto no importa demasiado de manera realista a menos que tenga una aplicación realmente grande. Solo codifico así por defecto.app.get('/hasToBeAdmin', (req, res, next) => { hasRole(req, res, next, 'admin'); }, (req,res) => { // regular route }); const hasRole = (req, res, next, role) => { if(role != user.role){ res.redirect('/NotInRole'); } next(); };fuente
Alternativamente, si no tiene demasiados casos o si el rol NO es una cadena:
function HasRole(role) { return function (req, res, next) { if (role !== req.user.role) res.redirect(/* ... */); else next(); } } var middlware_hasRoleAdmin = HasRole('admin'); // define router only once app.get('/hasToBeAdmin', middlware_hasRoleAdmin, function (req, res) { })fuente
Si tiene varios niveles de permisos, puede estructurarlos así:
const LEVELS = Object.freeze({ basic: 1, pro: 2, admin: 3 }); /** * Check if user has the required permission level */ module.exports = (role) => { return (req, res, next) => { if (LEVELS[req.user.role] < LEVELS[role]) return res.status(401).end(); return next(); } }fuente
Yo uso esta solución. Recibo un token jwt en body req y obtengo información de rol desde allí
//roleMiddleware.js const checkRole = role => { return (req, res, next) => { if (req.role == role) { console.log(`${role} role granted`) next() } else { res.status(401).send({ result: 'error', message: `No ${role} permission granted` }) } } } module.exports = { checkRole }Entonces, primero uso el middleware de autenticación para saber si es un usuario válido, y luego el middleware de rol para saber si el usuario tiene acceso a la ruta de la API
// router.js router.post('/v1/something-protected', requireAuth, checkRole('commercial'), (req, res) => { // do what you want... })Espero ser de utilidad
fuente