PassportJS serializeUser和deserializeUser执行流程

yea*_*ght 9 mongoose node.js express passport.js

我正在使用带有express的passportJS来通过本地策略验证用户身份.我看过几篇关于如何设置护照和执行流程的文章.虽然关于护照的大部分内容都可以通过搜索找出来,但是用户的序列化和反序列化使我感到困惑.

我知道它用于在会话中保存用户信息以进行持久登录.我的序列化和反序列化代码是

passport.serializeUser(function(user, done){
    done(null, user.id);
});

passport.deserializeUser(function(id, done){
    User.findById(id, function(err, user){
        done(err, user);
    });
});
Run Code Online (Sandbox Code Playgroud)

我的问题

1)谁调用并填充serializeUser和deserializeUser的参数?它如何访问用户对象?为了理解这一点,我添加了日志

 passport.serializeUser(function(user, done){
    console.log(arguments.callee.caller);
    done(null, user.id);
});
Run Code Online (Sandbox Code Playgroud)

在输出中得到[Function:pass]任何人都可以解释一下吗?

2)我使用mongodb来存储用户信息.MongoDB将_id作为文档的默认ID.理想情况下,serializeUser和deserializeUser应该使用user._id而不是user.id. 但它在user.id中工作正常,这在User用户中是不可用的.这是在控制台中打印的用户对象

{ _id: 5505f231b810dbd4098ac76a,
  __v: 0,
  google: {},
  twitter: {},
  facebook: {},
  local:
   { password: '$2a$08$9NGd0xNu0JbWMZ07ufyFRu8guwy147k8IBl5cAC4Y8APOuxreNI32',
     email: 'xxxx@xxx.com' } }
Run Code Online (Sandbox Code Playgroud)

这怎么可能?

3)一旦done执行方法,控制流程执行一次?

Jal*_*lal 19

经过长时间的搜索,我发现这篇文章非常清楚地解释了认证流程.

  • 对于serializeUser:
  1. 当用户提交登录表单时,会向/ login发出POST请求,导致执行 我们设置的passport.authenticate中间件.
  2. 由于该路由的身份验证中间件配置为处理本地策略,因此passport将调用我们的本地策略实现.
  3. Passport使用req.body.username和req.body.password并将其传递给本地策略中的验证功能.
  4. 现在我们做的事情是:从数据库加载用户并检查给定的密码是否与数据库中的密码匹配.
  5. 如果一切顺利,我们希望用户登录,我们调用done(null,user).
  6. 调用完成将使流程跳回 passport.authenticate.它传递了错误,用户和其他信息对象(如果已定义).
  7. 如果用户通过,中间件将调用req.login(附加到请求的护照功能).
  8. 这将调用我们之前定义的passport.serializeUser方法.
  • 对于deserializeUser:
  1. Express加载会话数据并将其附加到req.由于护照将序列化用户存储在会话中
  2. passport.session中间件是一种Pa​​ssport策略,如果在服务器中找到序列化的用户对象,它将把用户对象加载到req.user上.
  3. 在请求上调用passport.initialize,它会找到附加到会话的passport.user.接下来,调用passport.session.
  4. passport.session中间件调用我们设置的passport.deserializeUser.将加载的用户对象作为req.user附加到请求.

我希望它有所帮助.


Nar*_*oni 4

由于您正在使用 PassportJS,所以我假设您一定对它的工作原理有所了解。所以我会添加更多信息,我认为这会消除您的疑虑。

Passport 配置涉及三部分:

  1. 认证策略
  2. 应用中间件
  3. 会议

你的问题的答案在于第三部分,即会议。

如果身份验证成功,将通过用户浏览器中设置的 cookie 建立并维护会话。每个后续请求将不包含凭据,而是包含标识会话的唯一 cookie。为了支持登录会话,Passport 将对user会话中的实例进行序列化和反序列化。

根据您的实现,只有用户 ID 被序列化到会话中,从而使会话中存储的数据量保持较小。当后续收到请求时,用这个ID来查找用户,并将其恢复为req.user

在护照中,我们可以选择编写自己的序列化和反序列化逻辑,以便我们可以选择任何合适的数据库,而不受严格规则的束缚。

总而言之,身份验证成功后,用户对象将被序列化并存储在会话中,如果您调用req.user,那么您将能够检索相同的用户对象。