2012-10-04 33 views
36

Estoy intentando crear un middleware que pueda aceptar parámetros. ¿Cómo puede hacerse esto?Crear un middleware expressjs que acepte los parámetros

ejemplo

app.get('/hasToBeAdmin', HasRole('Admin'), function(req,res){ 

}) 

HasRole = function(role, req, res, next){ 
    if(role != user.role){ 
     res.redirect('/NotInRole); 
    } 

    next(); 
} 
+0

Ha, con lo solicitado mi pregunta exacta para mi escenario exacto, pero 6 años antes. SO es increíble. – aero

Respuesta

69
function HasRole(role) { 
    return function(req, res, next) { 
    if (role !== req.user.role) res.redirect(...); 
    else next(); 
    } 
} 

También quiero para asegurarse de que no hago 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(); 
    }) 
} 
+0

¡Funciona para mí! Gracias por el claro ejemplo. – facultymatt

+0

Simple y elegante. Muy agradable. –

+6

El segundo método almacena en caché los parámetros, que pueden no ser el comportamiento deseado. –

0
app.get('/hasToBeAdmin', function(req, res, next){ 
    hasRole(req, res, next, 'admin'); 
}, function(req,res){ // regular route }); 

var hasRole = function(req, res, next, role){ 
    if(role != user.role){ 
     res.redirect('/NotInRole'); 
    } 
    next(); 
}; 
+0

idea buena y simple. El middleware realmente es solo una función normal. ¿Por qué no pasarle otros valores? Por favor incluya req, res y el siguiente en la primera función. – zevero

+0

Mientras que el código a menudo habla por sí mismo, es bueno agregar alguna explicación a su código. Apareció en la cola de revisión, ya que las respuestas de solo código tienden a hacerlo. – Will

2

Alternativamente, si usted no tiene demasiados casos o si la función 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){ 

}) 
1

Si tiene varios niveles de permisos se podría estructurar como esto:

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(); 
    } 
} 
Cuestiones relacionadas