快速用户认证中间件,它应该做多少?

时间:2015-01-30 00:31:51

标签: javascript express middleware

我正在尝试学习快速会话和身份验证处理。

例如:

app.post('/login', authCredentials, function(req, res) {
   console.log("second")
});

function authCredentials(req, res, next) {
  //this happens first
  console.log(req.body) // => { username: etc, password: etc }
  next(); 
}

我的问题是我的authCredentials功能应该做多少? 例如,如果凭据是正确的,我可以做类似的事情 res.redirect('/index')。但是,一旦我这样做,第二个功能的目的是什么?

其他问题:

  1. 我如何处理无效凭证?
  2. 如果我authCredentials只是根据凭据返回truefalse,那么是否会破坏中间件流,因为它永远不会调用next()
  3. 可以在匿名回调中访问authCredentials中的任何内容吗?基本上在function(req, res) { }

2 个答案:

答案 0 :(得分:2)

答案取决于您的身份验证策略,即您使用会话标识符,访问令牌等等。

在任何一种情况下,我都建议您从身份验证中划分凭证交换(即登录)。

function usernamePasswordExchange(req,res,next){
  var username = req.body.username;
  var password = req.body.password;

  callToAuthService(username,password,function(err,user){
    if(err){
      next(err); // bad password, user doesn’t exist, etc
    }else{
      /*
        this part depends on your application.  do you use
        sessions or access tokens?  you need to send the user
        something that they can use for authentication on
        subsequent requests
      */
      res.end(/* send something */);
    }
  });
}

function authenticate(req,res,next){
  /*
    read the cookie, access token, etc.
    verify that it is legit and then find
    the user that it’s associated with
  */
  validateRequestAndGetUser(req,function(err,user){
    if(err){
      next(err); // session expired, tampered, revoked
    }else{
      req.user = user;
      next();
    }
  });
}

app.post('/login',usernamePasswordExchange);

app.get('/protected-resource',authenticate,function(req,res,next){
  /*
    If we are here we know the user is authenticated and we
    can know who the user is by referencing req.user
  */
});

免责声明:我在Stormpath工作,我们花了很多时间写作 验证码:)我刚刚写了我们最新的库stormpath-sdk-express, 它具体实现了我的建议

答案 1 :(得分:1)

您希望将authCredentials中间件添加到需要身份验证的每个端点。 app.post('/login')通常不需要任何内容​​,因为您想要访问此终点以实际获取凭据。

当凭据正确/有效时,您只需调用next(),工作流将跳转到下一个中​​间件或实际终点。如果出现错误,请调用带有next()等错误对象的next(new Error('could not authenticate');。向您的常规路由添加错误路由,错误将在那里处理:

app.use(function(err, req, res, next) {
    res.render('error', err);
});
  1. 现在应该回答。
  2. 中间件不返回值。它可以通过调用next()来调用res.send()或以不同方式结束该过程。
  3. 将变量从一个中间件传递到另一个中间件有不同的方法。最常见的可能是将所需值附加到req参数。
  4. authenticate是以下示例中的异步函数:

    function authCredentials(req, res, next) {
        authenticate(req.body, function(err, user) {
            if (err) {
                return next(err);
            }
            req.user = user;
            next();
        });
    }