如何将参数传递给 Express JS 中的中间件函数?

Posted

技术标签:

【中文标题】如何将参数传递给 Express JS 中的中间件函数?【英文标题】:How to pass a parameter to middleware function in Express JS? 【发布时间】:2019-03-09 22:15:28 【问题描述】:
// state edit route
app.get("/map/:symbol/edit", isLoggedIn, function(req, res)
  State.findOne(symbol: req.params.symbol, function(err, state)
    if(err)
      console.log(err);
     else
    
      res.render("edit", state: state);
    
  );
);

在上面的代码sn-p中,isLoggedIn是检查认证的中间件函数。其定义如下:

// middleware function
function isLoggedIn(req, res, next)
  if(req.isAuthenticated())
    return next();
  
  res.redirect("/admin");

那么,问题来了,如何将字符串、整数或路径变量等参数传递给中间件函数,以便在路由 url 中使用?

【问题讨论】:

从哪里传?中间件将始终在您的终止函数之前运行,并且中间件的运行顺序与您在 app.get() 等中定义它们的顺序相同。 我想要 isLoggedIn(var) 这样我就可以访问函数中的 var(req, res, next, var) @LarsHoldaas 很公平,但是你如何想象你将要调用 isLoggedIn?您永远不会自己调用它,而是 express 调用它以及中间件/终止函数链中的所有其他函数,并使用相同的三个参数:req、res 和 next。 现在,如果您的想法是要根据调用的 app.get/app.post 等进行不同的操作,您可以检查中间件中的 req.originalUrl。除此之外,您从未真正从代码中调用该函数。 Express 在收到请求时会为您执行此操作。 我建议您准确描述您想要的行为,我或其他人会为您提供如何实现该行为的好建议。但您具体要求的不是 express 的工作方式。 【参考方案1】:

这就是我使用它的方式,我接受了一点 Hardik Raval 的回答。

helpers.validateRole = (roles) => 
    return async (req, res, next) => 
        try 
            const authHeader = req.headers['authorization']
            const token = authHeader && authHeader.split(' ')[0]
            if (token == null) return res.json(error:true, msg: "Unauthorized")
            const user = jwt.decode(token)
            let isValid = false
            roles.map((r,i)=>
                if (r === user.role)
                    isValid = true
                
            )
            if (isValid)
                // User role is valid
                next();
            else
                // User role is not valid
                util.returnError("Unauthorized", res);
            
        
        catch (error) 
            next(error)
        
    

我是这样打电话的。

router.get(  "/requirements/list_of_requirements/:page/:rows",  isAuthenticated, validateRole([6]),  async (req, res) => 
//* All the logic
)

【讨论】:

我认为将用户角色存储在 JWT 中并不是一个好主意【参考方案2】:

我有同样的要求,这种方法适合我。

中间件文件validate.js

exports.grantAccess = function(action, resource)
    return async (req, res, next) => 
        try 
            const permission = roles.can(req.user.role)[action](resource);
            // Do something
            next();
        
        catch (error) 
            next(error)
        
    

route 文件中使用中间件。 grantAccess('readAny', 'user')

router.get("/",grantAccess('readAny', 'user'), async (req,res)=>
    // Do something     
);

【讨论】:

正是我想要的。干杯!【参考方案3】:

按照这种方法,它可能会为您完成这项工作

app.use(function(req, res, next)
    console.log(req);
    this.req = req;
    // assign value like this
    this.req.body.custom_data = ['zz', 'aaa', ....];
    next();
);

app.get("/map/:symbol/edit", isLoggedIn, function(req, res)
   State.findOne(symbol: req.params.symbol, function(err, state)
      if(err)
         console.log(err);
       else 
         res.render("edit", state: state);
      
   );
);

function isLoggedIn(req, res, next)
   console.log(req.body);
   if(req.isAuthenticated())
      return next();
   
   res.redirect("/admin");

【讨论】:

以上是关于如何将参数传递给 Express JS 中的中间件函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何将参数传递给 MEAN.js 包的 express.js 服务器端路由。

如何将参数传递给 Express post HTTP 方法?

如何将 URL 中的数组作为参数传递给 Promise.all

如何将参数传递给 React js 中的函数?

定义后无法将可选参数传递给express

如何将参数传递给节点js中的sql查询