71

我通过这个问题查看了错误处理应该如何在节点中工作Node.js + Express.js 应用程序的错误处理原则?,但我不确定护照在认证失败时会做什么。我有以下本地策略:

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' 控制台打印输出后,没有其他任何反应。我认为它应该在带有错误参数的下一条路径上继续,但它似乎没有这样做。这是怎么回事?

4

4 回答 4

171

策略实现与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. 提供的凭据无效(没有提供的电子邮件地址的用户,或密码不匹配);在这种情况下,您不会产生错误,但您将 afalse作为用户对象传递next(null, false):这将触发failureRedirect(如果您没有定义,则会生成 HTTP 401 Unauthorized 响应);
  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);
});
于 2013-03-29T21:13:36.513 回答
22

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/

于 2015-05-12T20:00:37.040 回答
3

您需要req.logIn(function (err) { });在回调函数中添加并执行成功重定向

于 2015-02-20T17:44:58.100 回答
0

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

  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' });    
    });
});
于 2021-10-06T04:47:01.583 回答