Express Passport (node.js) 错误处理

Posted

技术标签:

【中文标题】Express Passport (node.js) 错误处理【英文标题】:Express Passport (node.js) error handling 【发布时间】:2013-03-20 14:52:36 【问题描述】:

我已经通过this question Error handling principles for Node.js + Express.js applications? 查看了节点中的错误处理应该如何工作,但我不确定当护照通过身份验证失败时会做什么。我有以下 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);
    );
  
));

在我看到 'Error > some err' 控制台打印输出后,没有其他反应。我认为它应该在带有错误参数的下一条路径上继续,但它似乎没有这样做。怎么回事?

【问题讨论】:

【参考方案1】:

策略实现与passport.authenticate 一起工作,以验证请求并处理成功/失败。

假设你正在使用这条路线(它传递了一个电子邮件地址和一个密码):

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

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

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

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

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

如果您使用了failureFlash 安装了the connect-flash middleware,则提供的消息将存储在会话中,并且可以轻松访问,例如在模板中使用。

编辑:也可以自己完全处理身份验证过程的结果(而不是 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);
);

【讨论】:

谢谢!我想就我而言,我正在尝试通过 ajax 发送失败的响应,而不是进行重定向。查看护照文档,我认为这意味着我必须使用自定义函数回调来格式化我的路线。 如果有帮助,我编辑了我的答案以展示自己处理身份验证的可能方法:) 感谢“自己处理身份验证”编辑,这是救命稻草! 我使用了您的自定义身份验证代码,但是当我在未来的请求中调用 req.isAuthenticated 时,我得到了错误 @thebiglebowski11(我认为)你仍然需要调用 req.logIn()。这个答案证明了它***.com/a/26032067/2278963【参考方案2】:

你需要添加req.logIn(function (err) );并在回调函数中做成功重定向

【讨论】:

你能澄清你的答案吗?【参考方案3】:

Christian 说的是你需要添加函数

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/

【讨论】:

【参考方案4】:

一段时间过去了,现在最正确的代码是:

  passport.authenticate('local', (err, user, info) => 
    if (err) 
      return next(err); // will generate a 500 error
    
    // Generate a JSON response reflecting authentication status
    if (!user) 
      return res.status(401).send( error: 'Authentication failed' );
    
    req.login(user, (err) => 
      if (err) 
        return next(err);
      
      return res.status(202).send( error: 'Authentication succeeded' );    
    );
);

【讨论】:

以上是关于Express Passport (node.js) 错误处理的主要内容,如果未能解决你的问题,请参考以下文章

phonegap ajax 用户身份验证与 nodejs-express-mongodb-passport js

Express/Passport 创建会话但不向前端发送 cookie

使用 Passport.js、express-session 和 express-mysql-session 进行用户身份验证

使用 passport.js、mysql 和 express-session 保持登录状态

Node.js 和 Passport 对象没有方法 validPassword

在带有 React.js 前端的 Node.js 上使用 Passport.js 进行身份验证