我已经研究了如何通过this question Error handling principles for Node.js + Express.js applications?在node中处理错误,但我不确定passport在身份验证失败时会做什么.我有以下策略:

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);
    });
  }
));

在我看到"错误"之后>一些错误的控制台打印输出,没有其他事情发生.我认为它应该在下一条路径上继续使用错误参数,但它似乎没有这样做.发生什么事?

推荐答案

该策略的实现与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 and the connect-flash middleware,则提供的消息将存储在会话中,并且可以轻松访问,例如在模板中使用.

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

Node.js相关问答推荐

nest js控制器方法调用两次

为什么我的表单数据在我的POST请求中作为应用程序/json发送,为什么它返回错误请求错误?

如何在MongoDB中更新嵌套数组

Mongodb - 在数组数组中查找()

我应该转译我的 TypeScript 应用程序吗?

如何在mongodb中获取对象数组内部的数据

Mocha调用所有it回调模拟(测试中间件)

如何找到特定文档并更新数组中特定键的值?

fastify:流过早关闭

Google Calendar API FreeBusy 外部用户

AJAX 和 Node JS:在我的服务器中接收空数据

自定义 Docker 容器 Github 操作无法在 /github/workspace 中找到 Node 脚本

我可以向NPM添加调试脚本吗?

eslint - vscode 的可选链接错误

如何在 MongoDB 中查询引用的对象?

如何忽略文件 grunt uglify

使用 node.js 循环 JSON

我可以让 node --inspect 自动打开 Chrome

expressjs app.VERB 调用中的 next() 和 next('route') 有什么区别?

'node' 未被识别为内部或外部命令