您如何向外行解释Passport的序列化和反序列化方法的工作流?
1.调用passport.serializeUser
后,user.id
将转到哪里?
1.我们在它之后调用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);
});
});
我还在努力理解它。我有一个完整的工作应用程序,没有遇到任何错误。
我只想知道到底发生了什么?
任何帮助都很感激。
6条答案
按热度按时间ss2ws0br1#
1.调用
passport.serializeUser
后,user.id
将转到哪里?用户id(作为
done
函数的第二个参数提供)保存在会话中,稍后用于通过deserializeUser
函数检索整个对象。serializeUser
确定用户对象的哪些数据应该存储在会话中。serializeUser方法的结果作为req.session.passport.user = {}
附加到会话。例如,在这里,它将是(因为我们提供用户id作为键)req.session.passport.user = {id: 'xyz'}
1.我们在它后面调用
passport.deserializeUser
,它在工作流中的位置是什么?deserializeUser
的第一个参数对应于done
函数的用户对象的键(见1.)。因此,整个对象都是在该键的帮助下检索的。该键在这里是用户id(键可以是用户对象的任何键,如名称、电子邮件等)。在deserializeUser
中,该键与内存数组/数据库或任何数据源匹配。获取的对象作为
req.user
附加到请求对象可视化流程
vaj7vani2#
对于使用Koa和koa-passport的用户:
知道serializeUser方法中设置的用户密钥(通常是该用户的唯一ID)将存储在以下位置:
this.session.passport.user
当您在deserializeUser的
done(null, user)
中设置时,其中'user'是数据库中的某个用户对象:this.req.user
或this.passport.user
由于某种原因,当您在deserializeUser方法中调用done(null,user)时,
this.user
Koa上下文永远不会被设置。因此,您可以在调用app.use(passport.session())后编写自己的中间件,将其放入this.user中,如下所示:
如果你不清楚serializeUser和deserializeUser是如何工作的,可以在twitter上联系我。
sgtfey8w3#
Passport使用
serializeUser
函数将用户数据(在成功验证后)持久化到会话中。函数deserializeUser
用于从会话中检索用户数据。serializeUser
和deserializeUser
函数都检查传递给它们的第一个参数,如果它是function类型,serializeUser
和deserializeUser
什么也不做,而是将这些函数放在函数堆栈中,之后将调用这些函数(当传递的第一个参数不是function类型时)。使用中间件的顺序很重要,当一个新的授权请求开始时,查看会发生什么是很重要的:
sessionStore
的数据)。passport.initialize
将_passport
对象分配给请求对象,检查是否存在会话对象,如果会话对象存在,并且字段passport
存在于其中(如果不存在,则创建一个),将该对象分配给_passport
中的session
字段。最后,它看起来如下所示:因此,
session
字段引用了对象,该对象被赋值给req.session.passport
。passport.session
在req._passport.session
中查找user
字段,如果找到一个,则将其传递给deserializeUser
函数并调用它。deserializeUser
函数将req._passport.session.user
赋值给请求对象的user
字段(如果在req._passport.session.user
中找到一个)。这就是为什么,如果我们在serializeUser
函数中这样设置用户对象:然后我们需要解析它,因为它在
user
字段中保存为JSON
:所以,当你设置Passport时,
deserializeUser
函数第一次被调用,把你的回调放在_deserializers
函数栈中。第二次,它将在passport.session
中间件中被调用,把user
字段分配给请求对象。这也会在分配user
字段之前触发我们的回调(我们放在passport.deserializeUser()
中)。设置Passport时首先调用的
serializeUser
函数(类似于deserializeUser
函数),但它将用于序列化用户对象以保存在会话中。第二次,它将在login/logIn (alias)
方法中被调用,由Passport附加,并用于保存会话中的用户对象。serializeUser
函数还检查_serializers
堆栈是否具有已推送到其中的函数(其中一个是在设置Passport时添加的):并调用它们,然后分配用户对象将用户ID(已删除)或用户ID更改为
req._passport.session.user
。请务必记住,session
字段直接引用req.session
对象中的passport
字段。这样,用户在会话中保存了(因为req._passport.session
引用了对象req.session.passport
,passport.initialize
中间件在每次传入请求时都会修改req._passport.session
),当请求结束时,req.session
数据将存储在sessionStore
中。成功授权后,当第二个请求开始时会发生什么:
session
中间件从sessionStore
获取会话,我们的用户数据已经保存在其中passport.initialize
检查是否存在会话,并将req.session.passport
分配给req._passport.session
passport.session
检查req._passport.session.user
并将其反序列化。在此阶段(如果req._passport.session.user
为真),我们将具有req.user
,并且req.isAuthenticated()
返回true
。flmtquvp4#
您可以使用此代码升级旧的序列化和反序列化,请访问此帖子获取新的解决方案。
wydwbb8l5#
基本上,我们只是使用serializer将用户ID存储在会话中,当我们需要用户模型示例时,我们使用该用户ID在数据库中搜索,这是使用deserializer完成的。
只要会话是活动的并且用户被认证,
将始终对应于用户模型示例。
如果我们不将用户ID保存到会话中,并且如果存在任何重定向,我们将无法知道用户是否经过身份验证。
一旦用户被认证,将设置
req.session.passport.user
,因此所有将来的请求将知道用户已经被认证。希望这样简化。
erhoui1w6#
所以我在这上面停留了相当长的一段时间,所以我做了一个快速安装文件,这样就没有人再在这个垃圾上停留了
passportmgmt.js
现在只需导入并运行app.js中的passportSetupUwU函数,即可开始:
应用程序js试验