我的id
,model
或doc
或任何您想调用的字段中没有record
字段。那么done(null, user.id)
是如何工作的。我有一个_id
,但没有id
。看起来好像在数据库中与用户的_id
会话中添加了一个护照对象,但是它是如何自动获得_id
的呢?在文档中说
在此示例中,仅用户ID序列化到会话
它如何获得ID以及如何获得用户的?
我的代码中的类似示例:
passport.serializeUser(function(user, done){
done(null, user.id)
});
passport.deserializeUser(function(id, done){
User.findById(id, function(err, user){
done(err, user);
})
});
获取用户标识需要采取什么步骤?
我也有
passport.use("login", new LocalStrategy(function(username, password, done){
User.findOne({username : username}, function(err, user){
if(err){return done(err)}
if(!user){
return done(null, false, {message : "no User has that name"})
}
.......
我使用
passport.use()
的事实是否以某种方式将DB
中的用户连接到通行证方法。编辑可以说我想通过护照在名称字段上传输文档(用户),我应该使用user.name吗?
我也不太确定序列化的工作方式
最佳答案
那么done(null, user.id)
是如何工作的。我有一个_id
,但没有id
。
您正在使用Mongoose,它将在文档中添加一个所谓的virtual getter called id
并返回_id
属性。因此,在您的情况下,user.id
和user._id
都将起作用(并返回相同的值)。
我使用passport.use()
的事实是否将数据库中的用户连接到通行证方法。
是的,没有。您传递给passport.use()
的策略将实现身份验证过程。您必须实现如何根据数据库验证输入的用户信息。在示例代码中,调用了User.findOne()
,并根据提供的信息检查了该调用的结果(“ username
是有效的用户名吗?如果是,则password
属于该用户的密码是?”)。
如果用户名和密码匹配,则使用用户文档作为参数调用done
回调。该文档是Passport将传递到其他各个部分(例如,传递到passport.serializeUser()
(请参见下文))的内容。
我也不太确定序列化的工作方式。
序列化用于将有关用户的信息存储在“会话对象”中。该对象应该能够唯一地标识用户。而且由于user.id
(或user._id
)对于用户而言是唯一的,因此它是一个很好的属性。
这就是passport.serializeUser()
的用处:它传递了用户文档,并且应该(通过调用回调函数)为Passport提供有关该用户的唯一标识信息。因此done(null, user.id)
。
会话对象本身也由“会话密钥”唯一标识。该密钥存储在HTTP cookie中,并在用户成功登录后发送到浏览器。当浏览器打开您网站上的另一个页面时,它将发送该cookie,并使用cookie中的会话密钥从“会话存储”中检索会话对象。
会话对象包含唯一的用户ID,但不包含其余的用户信息。这就是passport.deserializeUser()
的来源:它传递了ID,并执行数据库查找以检索属于该ID的完整用户文档。这就是Passport将在您的路线处理程序中作为req.user
提供的功能。
如果所有这些步骤都成功执行(并非总是如此,因为cookie可能会过期,用户会被删除等),这意味着Passport能够肯定地识别用户,而不必登录再次。至少要等到会话期满为止。