39

我想在输入 url 时检查我的 web 应用程序用户的授权。但是当我使用单独的中间件来检查授权时,它对于已经存在的路由是没有用的,例如:

function authChecker(req, res, next) {
    if (req.session.auth) {
        next();
    } else {
       res.redirect("/auth");
    }
}

app.use(authChecker);
app.get("/", routes.index);
app.get("/foo/bar", routes.foobar);

authChecker无法检查输入这两个 url 的用户的权限。它仅适用于未指定的网址。

我看到了一种方法,我可以将authChecker放在路由和路由处理程序之间,例如:

app.get("/", authChecker, routes.index);

但是我怎样才能以一种简单的方式实现它,而不是把 authChecker 放在每条路线上呢?

4

3 回答 3

40

只要

app.use(authChecker);

是之前

app.use(app.router);

每个请求都会调用它。但是,您将得到“重定向过多”,因为它被调用为ALL ROUTES,包括/auth。所以为了解决这个问题,我建议将函数修改为:

function authChecker(req, res, next) {
    if (req.session.auth || req.path==='/auth') {
        next();
    } else {
       res.redirect("/auth");
    }
}

这样您也不会重定向 auth url。

于 2013-09-18T15:05:31.133 回答
26

有可能解决这个问题的方法,但这对我有用。

我喜欢为受保护和不受保护的路由创建一组中间件,然后在必要时使用。

var protected   = [authChecker, fetchUserObject, ...]
var unprotected = [...]

app.get("/", unprotected, function(req, res){
  // display landing page
})

app.get("/dashboard", protected, function(req, res){
  // display private page (if they get this far)
})

app.get("/auth", unprotected, function(req, res){
  // display login form
})

app.put("/auth", unprotected, function(req, res){
  // if authentication successful redirect to dashboard
  // otherwise display login form again with validation errors
})

这使得通过为每种类型的路由编辑数组来轻松扩展每个中间件范围的功能。它也让每条路由的功能更加清晰,因为它告诉我们它是什么类型的路由。

希望这可以帮助。

于 2013-09-09T19:40:49.613 回答
2

但是当我使用单独的中间件来检查授权时,它对于已经存在的路由是没有用的

Express 将按照添加到堆栈的顺序运行中间件。路由器是这些中间件功能之一。只要您authChecker在路由器之前进入堆栈,所有路由都将使用它,并且一切都会正常工作。

很可能您在 authChecker 之前拥有路由器,因为您在将 authChecker 放入堆栈之前定义了路由。确保将所有调用放在对,等的app.use任何调用之前,以避免 express 将路由器隐式注入到中间件堆栈中。app.getapp.post

于 2013-09-09T14:49:19.150 回答