node.js - Express:从另一个中间件调用一个中间件

标签 node.js express

我是 Express 4 的新手,我想知道如何实现这个东西:我正在使用 jwt 来验证我的 API 的使用者,为此我有一个漂亮的检查 jwt token 有效性的简单中间件:

var requireValidToken = function(req, res, next) {
  var token = req.body.token || req.query.token || req.headers['x-access-token'];
  if (token) {
    try {
      var decoded = jwt.verify(token, req.app.get('superSecret'));
    } catch(err) {
      return res.json({ success: false, message: 'Failed to authenticate token.' });  
    }
    req.user = decoded.user;
    next();
  } else {
    return res.status(403).send({ 
        success: false, 
        message: 'No token provided.' 
    });
  }
};

这工作得很好,但现在,我想扩展它以便能够检查用户的角色:

 router.get('/anAdminRoute', requireRole('ROLE_ADMIN'), function (req, res, next) {
      // some code...
 });

所以我为此添加了一个中间件:

var requireRole = function(role) {
  return function(req, res, next){
    // Dummy tests...
    if(req.user.role == roles.admin || req.user.role == role){
      next();
    } else {
      return res.status(403)({
        success: false,
        message: "Token valid, but you don't have the right permission to access this resource :)"
      });
    }
  }
}

但是由于这个 requireRole() 函数显然检查了一个有效的 jwt token ,我想知道如何在这个函数中调用我的 requireValidToken 中间件,因此不必为我想要保护的每条路由显式调用它。

一个简单的解决方案是不使用 requireValidToken 作为中间件,但我仍然希望能够使用它来保护某些路由

编辑:解决方案

链式中间件就是这么简单:

var middleware2 = function(param) {
  return function(req, res, next){
    middleware1(req, res, function(){
      // middleware2 code
    });
  }
}

如果有人感兴趣,我验证用户角色的最终工作解决方案:

var jwt = require('jsonwebtoken'),
  roles = require('../models/user').roles; 

// authentication middleware
// check if the given jwt token is valid
var requireValidToken = function(req, res, next) {
  var token = req.body.token || req.query.token || req.headers['x-access-token'];
  if (token) {
    try {
      var decoded = jwt.verify(token, req.app.get('superSecret'));
    } catch(err) {
      return res.json({ success: false, message: 'Failed to authenticate token.' });  
    }
    req.user = decoded.user;
    next();
  } else {
    return res.status(403).send({ 
        success: false, 
        message: 'No token provided.' 
    });
  }
};

var requireRole = function(role) {
  return function(req, res, next){
    requireValidToken(req, res, function(){
      if(req.user.role == roles.admin || req.user.role == role){
        next();
      } else {
        return res.status(403).send({
          success: false,
          message: "Token valid, but you don't have the right permission to access this resource :)"
        });
      }
    });
  }
}

module.exports = {
  requireValidToken: requireValidToken,
  requireRole: requireRole
}

最佳答案

完全误读了您的问题。如果您想在某些情况下调用 requireValidToken,您可以将 req 和 res 对象以及匿名回调传递给中间件函数。如何获得中间件功能很大程度上取决于您的应用程序架构,所以我假设我的上下文中有 requireValidToken:

var requireRole = function(role) {
  return function(req, res, next){
    // Dummy tests...

    requireValidToken(req, res, function () {
      if(req.user.role == roles.admin || req.user.role == role){
        next();
      } else {
        return res.status(403)({
          success: false,
          message: "Token valid, but you don't have the right permission to access this resource :)"
        });
      }
    });
  }
};

关于node.js - Express:从另一个中间件调用一个中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34468395/

相关文章:

json - 使用 POST 数据从 Node.js 提供静态文件

node.js - NodeJS Pdfmake 如何添加图像

javascript - 如何为每个 session 设置默认变量

node.js - Node 和浏览器中的 Webpack 外部

node.js - 如何使用docker将应用程序发布到heroku?

node.js - 字符串列表的变异变量 "$_v0_data"得到无效值 Graphql Node.js

node.js - 如何使用免费的 Dyno 在 Heroku 上使用 NodeJS 进行代理?

javascript - 使用 express.js 和 node.js 运行我的示例应用程序

javascript - req.body 检查是否包含特定字符

javascript - axios 数据正在破坏请求