oauth-2.0 使用Passport时,如果我使用令牌进行身份验证,那么序列化用户的目的是什么?

rggaifut  于 2022-10-31  发布在  其他
关注(0)|答案(1)|浏览(128)

我使用passport-google-oauth20作为我的应用程序的唯一身份验证形式。一切看起来都很好,我能够验证用户,并使用verify回调passport提供的数据库存储他。
在这个应用程序中,我只会使用谷歌来验证用户,并检查他是否存在或不在数据库中。我不会向谷歌提出更多的请求,或从谷歌获取更多的信息。
我注意到passport的回调函数背后有很多神奇的东西,我对serializeUserdeserializeUser的工作原理有一个模糊的了解,但我不确定 * 何时 * 有必要。
passport提供的回调函数在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('/');
    }
);

我可以得到配置文件和所有需要的信息。我还需要序列化用户吗?

rryofs0p

rryofs0p1#

serializeUser和deserializerUser函数用于设置cookie和阅读该cookie。
在google oauth中,当一个用户第一次登录google账户时,你会找到他的个人资料,并找到一个唯一的标识属性保存在数据库中,这个标识属性应该是profile.id,所以你会把用户的profile.id保存在数据库中。
下一次,当用户登录时,您需要识别该用户,否则您将profile.id一遍又一遍地保存同一个www.example.com。为了记住用户,您创建了cookie。当用户登录时,您获取该profile.id并查询该profile.id是否保存在数据库中。此操作在passport回调函数中完成,如果用户存在,passport将有权访问该用户。

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)
    })
})

相关问题