node.js - 使用 Passport,如果我使用令牌进行身份验证,序列化用户的目的是什么?
问题描述
我将passport-google-oauth20
其用作我的应用程序的唯一身份验证形式。一切似乎都很好,我可以使用verify
回调护照提供的身份验证用户并将他存储在数据库中。
在这个应用程序中,我只会使用 google 对用户进行身份验证并检查他是否存在于数据库中。我不会向谷歌提出更多请求,也不会从谷歌获取更多信息。
我注意到护照的回调函数背后发生了很多神奇的事情。我对如何serializeUser
和deserializeUser
工作有一个模糊的理解,但我不确定什么时候有必要。
护照提供的回调函数在localStorage上设置了一个JWT,所以即使我设置{ session: false }
了重定向选项,我还需要序列化用户吗?
这是一些清除问题的代码
passport.use(
new GoogleStrategy({
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: 'http://localhost:3000/auth/google/redirect'
},
(accessToken, refreshToken, profile, done) => {
// console.log('TCL: profile', profile); -> Gives profile info
// console.log('TCL: refreshToken', refreshToken); -> Null
// console.log('TCL: accessToken', accessToken);
// This attaches the user profile to the req object
done(null, profile);
})
);
以下是路线:
app.use(passport.initialize());
app.get(
'/auth/google',
passport.authenticate('google', { scope: ['profile', 'email'] })
);
app.get(
'/auth/google/redirect',
passport.authenticate('google', { session: false }),
(req, res) => {
console.log(req.user);
res.redirect('/');
}
);
我能够获得个人资料和我需要的所有信息。我还需要序列化用户吗?
解决方案
serializeUser 和 deserializerUser 函数用于设置 cookie 和读取该 cookie。
在 google oauth 中,当用户首次使用 google 帐户登录时,您会访问其个人资料并找到要保存在数据库中的唯一标识属性。该标识属性应该是 profile.id。因此,您将用户的 profile.id 存储在数据库中。
下次,当用户登录时,您需要识别用户,否则您将一遍又一遍地保存相同的 profile.id。为了记住用户,您创建 cookie。当用户登录时,您获取该 profile.id 并查询该 profile.id 是否保存在数据库中。此操作在护照回调函数中完成,如果用户存在,则护照将有权访问该用户。
passport.use(new GoogleStrategy({
clientID:keys.googleClientID,
clientSecret:keys.googleClientSecret,
callbackURL:"/auth/google/callback"}, (accessToken,refreshToken, profile,done)=>{
User.findOne({googleId:profile.Id}).then((user)=>{
if(user){ //it checks if the user is saved in the database
done(null,user)
}else {
new User({googleId:profile.id}).save().then((user)=>done(null,user))
}
})
}))
当passport.js 访问到用户后,它会自动调用serializeUser 函数,获取用户唯一标识的属性user.id,并将其注入到cookie 中,该cookie 发送到客户端响应头。
passport.serializeUser((user,done)=>{
//user.id is not profile id. it is id that created by the database
done(null,user.id)
})
一旦浏览器收到响应,它将cookie保存在一个文件中,当它向同一服务器发出后续请求时,它会自动将该cookie附加到请求中。Passport.js 将提取唯一标识信息 user.id 并将其传递给数据库,数据库将识别客户端。
passport.deserializeUser((id,done)=>{
User.findById(id).then((user)=>{
done(null,user)
})
})
推荐阅读
- reactjs - 从 iframe 更新本地存储后强制重新渲染组件
- jquery-scrollify - 我的页面偶尔会卡在滚动的中间
- mongodb - 使用 Spring Boot 的 MongoDB 聚合管道
- sockets - 来自广播节点的 UDP 冲突是否可能?
- python - 在 Tornado 中关闭 cookie
- php - 处理 php : Scanimage -L (usb)
- python-3.x - 气流记录 BrokenPipeException
- javascript - FlatList renderItem 被多次调用
- java - 一台计算机损坏 Excel 文件(通过我的程序通过 Apache POI 创建),而其他计算机工作正常
- android - 如何使用 sqlite 数据设置多个警报?