检查每个 node.js 请求以获取身份验证凭据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7951810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 14:42:35  来源:igfitidea点击:

Check each node.js request for authentication credentials

authenticationnode.jsconnectexpress

提问by Patrick

I'm using node.js with Express and connect-auth to authenticate users.

我正在使用带有 Express 和 connect-auth 的 node.js 来验证用户。

This is the verification when requesting /index:

这是请求/index时的验证:

if(req.isAuthenticated()) {
  res.redirect('/dashboard');
} else {
  res.render('index', { layout: 'nonav' });
}

However, after logging out and going back to f.e. '/dashboard', I can see the dashboard.

但是,在注销并返回 fe '/dashboard' 后,我可以看到仪表板。

How can I put the authentication check to every request to make sure there's a valid user at all times?

如何对每个请求进行身份验证检查以确保始终存在有效用户?

UpdateI don't have any problems with the authentication, everything works fine! I need a solution which checks every route/request if there's a valid user, without putting a function or if-statement in the route-implementation, as the whole App needs a valid user anyway. The Express-Authentication-Example uses "restrict" in the route-definition, which is close, but with many routes it can easily be forgotten.

更新我的身份验证没有任何问题,一切正常!我需要一个解决方案来检查每个路由/请求是否存在有效用户,而无需在路由实现中放置函数或 if 语句,因为无论如何整个应用程序都需要一个有效用户。Express-Authentication-Example 在路由定义中使用了“restrict”,这很接近,但在许多路由中很容易被遗忘。

回答by Zikes

app.all('*',function(req,res,next){
    if(req.isAuthenticated()){
        next();
    }else{
        next(new Error(401)); // 401 Not Authorized
    }
});
// NOTE: depending on your version of express,
// you may need to use app.error here, rather
// than app.use.
app.use(function(err,req,res,next){
    // Just basic, should be filled out to next()
    // or respond on all possible code paths
    if(err instanceof Error){
        if(err.message === '401'){
            res.render('error401');
        }
    }
});

If you define the allroute before routes which require authentication and after routes which do not (such as the home page, login, etc) then it should only affect the routes that need it. Alternatively you could use a RegExp instead of '*', which would include a subpath or list of paths that require authentication.

如果您all在需要身份验证的路由之前和不需要身份验证的路由之后(例如主页、登录等)定义路由,那么它应该只影响需要它的路由。或者,您可以使用 RegExp 而不是'*',这将包括需要身份验证的子路径或路径列表。

Another option would be to create a function to include in each route that requires auth:

另一种选择是创建一个函数以包含在每个需要身份验证的路由中:

function IsAuthenticated(req,res,next){
    if(req.isAuthenticated()){
        next();
    }else{
        next(new Error(401));
    }
}
app.get('/login',function(req,res,next){
    res.render('login');
});
app.get('/dashboard',IsAuthenticated,function(req,res,next){
    res.render('dashboard');
});
app.get('/settings',IsAuthenticated,function(req,res,next){
    res.render('settings');
});

回答by Aleksei Zabrodskii

You can use sessionsmechanism provided by connect. Put this code in app.configure()to enable it:

您可以使用sessions提供机制connect。输入此代码app.configure()以启用它:

  app.use(express.cookieParser());
  app.use(express.session({
    secret: 'some string used for calculating hash'
  }));

After that, you′ll be able to use req.sessionobject (different for each request) to store your authentication data (or anything else). So, your example code will look something like this:

之后,您将能够使用req.session对象(每个请求不同)来存储您的身份验证数据(或其他任何东西)。因此,您的示例代码将如下所示:

if (req.session && req.session.authorized) {
  res.redirect('/dashboard');
}
else {
  res.render('index', {layout: 'nonav'});
}

And authentication will look like this:

身份验证将如下所示:

req.session.authorized = checkPassword(login, passw);

Logout:

登出:

req.session.destroy();

More info can be found here.

更多信息可以在这里找到。

回答by Nelo Mitranim

Another way is to app.use a middleware function. (Example in CoffeeScript.)

另一种方法是 app.use 一个中间件功能。(CoffeeScript 中的示例。)

# middleware
authKick = (req, res, next) ->
  if not do req.isAuthenticated then return res.redirect '/login'
  return do next

# apply
app.use authKick

This will work on each request without having to touch the routes.

这将适用于每个请求,而无需触及路线。