Anu*_*hav 300 authentication serialization node.js express passport.js
您如何解释Passport序列化和反序列化方法的工作流程.
user.id去哪儿passport.serializeUser打电话?
我们正在呼吁passport.deserializeUser它在哪里适合工作流程?
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
// where is this user.id going? Are we supposed to access this anywhere?
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
Run Code Online (Sandbox Code Playgroud)我仍然试图绕过它.我有一个完整的工作应用程序,并没有遇到任何类型的错误.
我只是想了解这里到底发生了什么?
任何帮助表示赞赏.
A.B*_*A.B 391
user.id去哪儿passport.serializeUser打电话?
用户id(作为done函数的第二个参数提供)保存在会话中,稍后用于通过deserializeUser函数检索整个对象.
serializeUser确定用户对象的哪些数据应存储在会话中.serializeUser方法的结果作为附加到会话req.session.passport.user = {}.例如,它将是(因为我们提供用户ID作为键)req.session.passport.user = {id: 'xyz'}
- 我们正在呼吁
passport.deserializeUser它在哪里适合工作流程?
第一个参数deserializeUser对应于赋予done函数的用户对象的键(参见1.).因此,您可以借助该密钥检索整个对象.这里的密钥是用户id(密钥可以是用户对象的任何密钥,即名称,电子邮件等).在deserializeUser该密钥中与内存数组/数据库或任何数据资源匹配.
获取的对象作为附加到请求对象 req.user
视觉流程
passport.serializeUser(function(user, done) {
done(null, user.id);
}); ?
?
?
?????????????????????? saved to session
? req.session.passport.user = {id: '..'}
?
?
passport.deserializeUser(function(id, done) {
?????????????????
?
?
User.findById(id, function(err, user) {
done(err, user);
}); ???????????????? user object attaches to the request as req.user
});
Run Code Online (Sandbox Code Playgroud)
yva*_*her 18
对于任何使用Koa和koa护照的人:
知道在serializeUser方法中设置的用户密钥(通常是该用户的唯一ID)将存储在:
this.session.passport.user
当您done(null, user)在deserializeUser中设置'user'是数据库中的某个用户对象时:
this.req.user
要么
this.passport.user
出于某种原因,this.user当您在deserializeUser方法中调用done(null,user)时,Koa上下文永远不会被设置.
因此,您可以在调用app.use(passport.session())之后编写自己的中间件,将其放入this.user中,如下所示:
app.use(function * setUserInContext (next) {
this.user = this.req.user
yield next
})
Run Code Online (Sandbox Code Playgroud)
如果你不清楚serializeUser和deserializeUser是如何工作的,那就在twitter上点击我吧.@yvanscher
Passport 使用serializeUser函数将用户数据(成功验证后)保存到会话中。函数deserializeUser用于从会话中检索用户数据。
这两个serializeUser和deserializeUser功能检查传递给他们的第一个参数,如果它的类型的功能,serializeUser和deserializeUser什么也不做,而是把这些功能在堆栈中的功能,将被调用,之后(在传递第一参数的数据类型的功能不是)。Passport 需要以下设置来在会话中进行身份验证后保存用户数据:
app.use(session({ secret: "cats" }));
app.use(passport.initialize());
app.use(passport.session());
Run Code Online (Sandbox Code Playgroud)
使用的中间件的顺序很重要。重要的是要看到,当新的授权请求开始时会发生什么:
会话中间件创建会话(使用来自 的数据sessionStore)。
passport.initialize将_passport对象分配给请求对象,检查是否存在会话对象,如果存在,并且其中存在字段passport(如果不存在 - 创建一个),将该对象分配给session字段 in _passport。最后,它看起来像这样:
req._passport.session = req.session['passport']
Run Code Online (Sandbox Code Playgroud)
因此,session字段引用对象,分配给req.session.passport.
passport.session在 中查找user字段req._passport.session,如果找到,则将其传递给deserializeUser函数并调用它。deserializeUser函数分配req._passport.session.user给user请求对象的字段(如果在 中找到req._passport.session.user)。这就是为什么,如果我们serializeUser像这样在函数中设置用户对象:
passport.serializeUser(function(user, done) {
done(null, JSON.strignify(user));
});
Run Code Online (Sandbox Code Playgroud)
然后,我们需要分析它,因为它被保存为JSON在user外地:
passport.deserializeUser(function(id, done) {
// parsed user object will be set to request object field `user`
done(err, JSON.parse(user));
});
Run Code Online (Sandbox Code Playgroud)
因此,deserializeUser当您设置 Passport 时,首先调用函数以将您的回调放入_deserializers函数堆栈中。第二次,它将在passport.session中间件中调用以将user字段分配给请求对象。这也会passport.deserializeUser()在分配user字段之前触发我们的回调(我们放入)。
serializeUser在设置 Passport 时首先调用函数(类似于deserializeUser函数),但它将用于序列化用户对象以保存在会话中。第二次,它会在login/logIn (alias)Passport 附加的方法中被调用,并用于在会话中保存用户对象。serializeUser函数还检查_serializers已经推送到它的函数的堆栈(其中一个添加,当我们设置 Passport 时):
passport.serializeUser(function(user, done) ...
Run Code Online (Sandbox Code Playgroud)
并调用它们,然后将用户对象(strignified)或用户 id 分配给req._passport.session.user. 重要的是要记住session字段直接引用对象中的passport字段req.session。以这种方式用户保存在会话中(因为req._passport.session 引用 object req.session.passport,并且req._passport.session在每个传入请求中被passport.initialize中间件修改)。当请求结束时,req.session数据将存储在sessionStore.
成功授权后,当第二个请求开始时会发生什么:
session中间件从中获取会话sessionStore,我们的用户数据已保存在其中passport.initialize检查是否有会话并分配req.session.passport给req._passport.sessionpassport.session检查req._passport.session.user并反序列化它。在这个阶段(如果req._passport.session.user是真的),我们将拥有req.user并req.isAuthenticated()返回true。