【问题标题】:How to get name of next middleware function in Express.JS如何在 Express.JS 中获取下一个中间件函数的名称
【发布时间】:2021-11-04 04:13:04
【问题描述】:

我正在尝试获取特定请求路由中的中间件函数的名称。 假设我实现了以下代码:

const authorizeRoute = (req,res,next) => {
  let nextFunctionName = SomeFunctionToRetrieveTheNameOfTheNextMiddlewareToBeCalled()
  if (isUserAuthorized(req.user.id, nextFunctionName)) next()
}

app.use(authorizeRoute)
app.get("/users", controller.getUsers)
app.get("/users/:id/posts", controller.getUserPosts)

我希望authorizeRoute 中间件能够获取堆栈中下一个要调用的中间件函数的名称。

例如,如果有 "/users"GET 请求,我希望 nextFunctionName 具有 "getUsers" 或“controller.getUsers”或类似的值。 或者GET "/users/:id/posts" 具有相同的nextFunctionName 以成为"getUserPosts" 或其他东西。

我该怎么做?

我还是 Express 和 Node 甚至 javascript 的新手。我该怎么做呢?

我知道这是可能的,因为已经有一种方法可以在 javascript 中将函数名作为字符串获取。

someFunction.name // gives "someFunction" returned as a string

所以我知道这是可以做到的。我只是不知道,如何。

附:我知道有其他方法可以达到预期的效果,但我对此的需求并没有完全反映在上面的 sn-p 中,但我尽力让它展示出来。

【问题讨论】:

  • 那么,您尝试next.name 了吗?但我不认为next 实际上是下一个中间件,而是 express 提供的一个包装器。
  • @Bergi next.name 将“next”作为字符串。除了。 next() 不直接调用 next 中间件函数。它还有其他功能,我对此一无所知。
  • 你真的不应该使用函数名来选择授权。相反,将它明确地提供给路线 - 这也将通过许多不同的路线更好地扩展:app.get("/users", authorizeRoute("users"), controller.getUsers); app.get("/users/:id/posts", authorizeRoute("posts"), controller.getUserPosts);
  • 我知道这是一种方法。但是已经有一个数据库来控制对每条路线的访问。就像我说的。 sn-p 并不能完全说明我为什么需要它;只是什么。
  • 那么你为什么需要它呢?你想要的可能是不可能的。

标签: javascript express middleware


【解决方案1】:

想通了。我不能让中间件使用app.use 获取路由的堆栈,但如果将中间件放在路由的处理程序中,它将起作用。

const SomeFunctionToRetrieveTheNameOfTheLastMiddleware(req) => {
  let stack = req.route.stack
  return stack[stack.length-1].name
}

const authorizeRoute = (req,res,next) => {
  let nextFunctionName = SomeFunctionToRetrieveTheNameOfTheLastMiddleware(req)
  if (isUserAuthorized(req.user.id, nextFunctionName)) next()
}

app.get("/users", authorizeRoute, controller.getUsers)
app.get("/users/:id/posts", authorizeRoute, controller.getUserPosts)

我在问题本身就有问题的答案?

【讨论】:

  • 谢谢!我不知道请求中的路由堆栈。而且它不存在使用特定路线之外的直接中间件。干得好!
【解决方案2】:

你不想做一些动态的事情,保持简单。为什么不这样做:

const nextFunctionName = (user)=>{
    // blah blah blah (something synchronous not asynchronous)
}

const authorizeRoute = (req,res,next) => {

  if (isUserAuthorized(req.user?.id)){
      nextFunctionName(req.user)
    }

   next()
}

但看起来你实际上只是想这样做:

const nextFunctionName = (user, next)=>{
    // blah blah blah
    next();
}

const authorizeRoute = (user, next) => {
  if (isUserAuthorized(user.id)){
      nextFunctionName(user, next); // pass in the next callback
    } else {
      next()
    }
  
}

【讨论】:

  • 嗯? nextFunctionName 什么时候变成了一个函数。它应该是一个字符串,它是下一个中间件的名称
  • 是的,完全正确 :) 考虑一下
  • isUserAuthorized 函数检查数据库中的用户 ID 和用户尝试访问的函数。这不是身份验证
  • 你的方法肯定行得通。但我并没有试图改变程序的功能,如果我是的话,我就不必问这个问题了,那里有很多资源可以替代。我正在寻找的是填补我的知识空白,获取特定路线中的中间件功能的名称。这就是我所缺乏的。其他一切都是次要的。
猜你喜欢
  • 2011-01-10
  • 2011-10-26
  • 2018-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
相关资源
最近更新 更多