如何使用 passport-local 登录用户并显示错误消息?

How to login users with passport-local and display an error message?

所以我一直在尝试使用 PassportJs 在我的 VueJs 应用程序上编写一个身份验证系统。我写了一个函数来初始化 PassportJs 的基础知识,如下所示:

module.exports = {
  passport: function () {
    authenticateUser = async (email, password, done) => {
      User.findOne({ email: email }, async (err, user) => {
        if (user == null) return done(null, false, { msg: 'No user registered with this email' })

        try {
          if (await bcrypt.compare(password, user.password)) {
            return done(null, user)
          } else {
            return done(null, false, { msg: "Password incorrect" })
          }
        } catch (e) {
          return done(e)
        }
      })
    }

    passport.use(new LocalStrategy({ usernameField: 'email', }, authenticateUser));
    passport.serializeUser((user, done) => {
      console.log('passport serializeUser')
      done(null, user.id)
    })

    passport.deserializeUser((id, done) => {
      console.log('passport deserializeUser')
      User.findById(id, (err, user) => {
        done(err, user)
      })
    })
  },
};

现在,字面上 唯一 我需要的是在前端显示正确的错误消息。

此代码适用于显示错误消息,但不适用于实际登录用户:

router.post('/login', function (req, res, next) {
  passport.authenticate('local', function (err, user, info) {
    if (err) { return next(err); }
    if (!user) {
      console.log('mand?????: ', info)
      res.status(401).json({ msg: info.msg });
      return;
    }
  })(req, res, next);
});

我可以看到这段代码得到 运行 (await bcrypt.compare(password, user.password)) 但它没有序列化用户。请求只是保持 'pending' 但没有完成。

此代码适用于实际登录用户,但不适用于显示错误消息:

router.post('/login', passport.authenticate('local'))

我哪里错了?我如何才能成功登录用户,同时显示正确的错误消息,如 passportjs done() 函数中声明的那样?

查看有关 authenticate() 方法的 passport 文档。

When using a custom callback, it becomes the application's responsibility to establish a session (by calling req.login()) and send a response.

所以在你的第一个场景中,你需要明确地建立一个会话——passport 不会自动为你做这件事。

关于您未使用自定义回调的第二种情况:

By default, if authentication fails, Passport will respond with a 401 Unauthorized status, and any additional route handlers will not be invoked.

据我了解,使用此设置,不会使用设置为 Strategy 验证回调一部分的闪存消息 - 除非指定了 redirect 选项,这是您不希望的这里。

因此,您可能应该选择第一种情况,以便能够使用 Strategy 验证回调闪存消息自定义错误响应。只要确保在登录成功时建立会话即可。

http://www.passportjs.org/docs/authenticate/

编辑:我刚刚 运行 通过了一个快速测试,看起来你应该能够摆脱 Strategy 验证回调 return 错误将 error.message 属性 设置为您要作为响应发送的任何错误消息 - 根本不需要自定义回调和闪现消息。请注意,在这种情况下,passport 实际上将错误消息的响应主体设置为文本。

所以例如代替:

done(null, false, { msg: 'No user registered with this email' })

你会做:

done(new Error('No user registered with this email')