验证后对没有密码的用户进行一次验证

Authenticate user without password once after verification

我有一个标准的 LocalStrategy Passport.js 身份验证策略。在此期间,LocalStrategy 使用 bcrypt 根据数据库检查密码,并对会话进行身份验证。如果您需要查看代码:

const LocalStrategy = passportLocal.Strategy;
const userStrategyHandler = async (username, password, done) => {
  const [ userFetchErr, user ] = await to(userService.findByEmail(username));

  // ...

    const authResult = await authService.comparePassword(password, user.password);

  // ...

  return done(null, user);
};

const userStrategy = new LocalStrategy(userStrategyHandler);
passport.use(userStrategy);

但是,当他们注册时,我会发送一封电子邮件来验证用户的帐户。当他们单击 link 时,它当前会将他们重定向到主页。他们没有登录,这不是一个很好的用户体验,但是在 /verify 路由中的重定向之前有机会让用户登录

有没有办法在服务器端对用户进行身份验证,而不需要调用 Passport LocalStrategy?这样我就可以在验证后一次性登录用户。之后,用户将使用他们的密码进行身份验证。或者有其他方法可以达到这个结果吗?

对于这种情况,您应该在 jwt 的基础上创建如下所示的 link 并发送给使用电子邮件:

https://website/verify#token=eyJpZCI6Nzk5OTEwNzc3NjMyMzI1NjU0LCJlbWFpbCI6Im0ueS5haG

这个令牌应该存储在一个新的 table 中,它有两列,tokenstatus,点击 [= 后状态首先是 true 21=] 在电子邮件中,调用 /verify 路由,状态将为 false 并且对令牌无效,因此如果令牌有效且状态为真,您可以将用户重定向到主页,没有护照就可以做你想做的 ``

其实很容易解决这个问题。我添加了另一列 (isInitialVerification BOOLEAN NOT NULL DEFAULT FALSE)。然后,在 /verify 路线上,我将 isIntialVerification 设置为 true。在 Passport LocalStrategy 中,我只是检查了列值,然后将其重置为 false。

确保在无法将 isInitialVerification 值更新回 false 时抛出错误(即 return done(err, ...)),以避免潜在的永久身份验证 - 最糟糕的情况情况是他们必须手动登录。

以上内容不正确。任何人都可以在 isInitialVerification 和下一个请求之间发送请求,并进行身份验证。请参阅 Mohammad 的回答以获得可能的解决方案