138

我正在尝试创建一个可以接受参数的中间件。如何才能做到这一点?

例子

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

})

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

   next();
}
4

6 回答 6

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

我还想确保我不会制作同一函数的多个副本:

function HasRole(role) {
  return HasRole[role] || (HasRole[role] = function(req, res, next) {
    if (role !== req.user.role) res.redirect(...);
    else next();
  })
}
于 2012-10-04T23:07:37.917 回答
19
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();
};
于 2012-10-04T23:20:39.857 回答
6

或者,如果您没有太多案例或角色不是字符串:

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) {

})
于 2016-05-20T06:30:02.383 回答
5

我使用这个解决方案。我在正文 req 中收到一个 jwt 令牌,并从那里获取角色信息

//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 }

所以首先我使用 auth 中间件来知道是否是一个有效的用户,然后使用角色中间件来知道用户是否可以访问 api 路由

// router.js

router.post('/v1/something-protected', requireAuth, checkRole('commercial'), (req, res) => {
    // do what you want...
})

我希望有用

于 2020-10-02T01:38:14.577 回答
2

如果你有不同的权限级别,你可以像这样构造它们:

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();
  }
}
于 2017-03-24T15:01:31.180 回答
1

既然我们在 2021 年,为什么不使用 ES6 语法?...使用 NodeJS v14.16.1,下面的示例就像一个魅力:-)

使用快速路由器

const someFunc = ({ option1, option2 }) =>
 router.get("/", (req, res, next) => {
    
 // code
    
 next();
});

module.exports = someFunc;

或者

const someFunc = ({ option1, option2 }) =>
     (req, res, next) => {
        
     // code
        
     next();
    };
    
 module.exports = someFunc;

...然后将其称为:

const someFunc = require('./middlewares/someFunc.js');
app.use(someFunc({option1: 'test', option2: false ));
于 2021-04-21T08:05:43.847 回答