Express Passport(node.js)错误处理


69

我已经研究了如何通过此问题在节点中进行错误处理,Node.js + Express.js应用程序的错误处理原理?,但是我不确定护照认证失败时在做什么。我有以下LocalStrategy:

passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' },
  function(email, password, next) {
 
    User.find({email: UemOrUnm}, function(err, user){
      if (err) { console.log('Error > some err'); return next(err); }
      if (!user) { console.log('Error > no user'); return next('Incorrect login or password'); } 

      if (password != user.password) {
        return next(Incorrect login or password);
      }
      return next(null, user);
    });
  }
));

在看到“错误>某些错误”控制台打印输出后,什么都没有发生。我认为它应该在带有错误参数的下一条路径上继续,但是似乎没有这样做。这是怎么回事?

Answers:


168

策略实施与passport.authenticate验证请求和处理成功/失败一起使用。

假设您正在使用此路由(已通过电子邮件地址和密码传递):

app.post('/login', passport.authenticate('local', {
  successRedirect: '/loggedin',
  failureRedirect: '/login', // see text
  failureFlash: true // optional, see text as well
});

这将调用该策略中的代码,其中可能发生以下三种情况之一:

  1. 尝试获取用户信息时发生内部错误(例如数据库连接已断开);这个错误将转嫁:next(err); 这将由Express处理并生成HTTP 500响应;
  2. 提供的凭据无效(没有用户使用提供的电子邮件地址,或者密码不匹配);在这种情况下,你不产生一个错误,但你传递一个false为用户对象:next(null, false); 这将触发failureRedirect(如果您未定义,则会生成HTTP 401未经授权的响应);
  3. 一切检查出来,你有一个有效的用户对象,所以你把它传递:next(null, user); 这将触发successRedirect;

如果验证无效(但不是内部错误),则可以在回调中传递额外的消息:

next(null, false, { message : 'invalid e-mail address or password' });

如果您已使用failureFlash 安装了Connect-Flash中间件,则所提供的消息将存储在会话中,并且可以轻松访问,例如在模板中使用。

编辑:也有可能自己完全处理身份验证过程的结果(而不是Passport发送重定向或401):

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) {
      return next(err); // will generate a 500 error
    }
    // Generate a JSON response reflecting authentication status
    if (! user) {
      return res.send({ success : false, message : 'authentication failed' });
    }
    // ***********************************************************************
    // "Note that when using a custom callback, it becomes the application's
    // responsibility to establish a session (by calling req.login()) and send
    // a response."
    // Source: http://passportjs.org/docs
    // ***********************************************************************
    req.login(user, loginErr => {
      if (loginErr) {
        return next(loginErr);
      }
      return res.send({ success : true, message : 'authentication succeeded' });
    });      
  })(req, res, next);
});

2
谢谢!我想以我为例,我试图通过ajax发送失败的响应,而不是进行重定向。查看护照文档,我认为这意味着我必须使用自定义函数回调来格式化我的路线。
Omid Ahourai

3
如果有帮助,我编辑了答案以显示自己处理身份验证的可能方法:)
robertklep

1
感谢您进行“自己处理身份验证”编辑,这真是一条命!
wulftone 2014年

3
我使用了您的自定义身份验证代码,但是当我在以后的请求中调用req.isAuthenticated时,我会得到错误的消息
thebiglebowski11

1
@ thebiglebowski11(我认为)您仍然需要调用req.logIn()。这个答案证明了它stackoverflow.com/a/26032067/2278963
anthonygore 2015年

20

克里斯汀说的是您需要添加功能

req.login(user, function(err){
  if(err){
    return next(err);
  }
  return res.send({success:true});
});

因此,整个路线将是:

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) {
      return next(err); // will generate a 500 error
    }
    // Generate a JSON response reflecting authentication status
    if (! user) {
      return res.send(401,{ success : false, message : 'authentication failed' });
    }
    req.login(user, function(err){
      if(err){
        return next(err);
      }
      return res.send({ success : true, message : 'authentication succeeded' });        
    });
  })(req, res, next);
});

来源:http//passportjs.org/guide/login/


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.