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

时间:2019-04-13 20:02:05

标签: oauth-2.0 passport-google-oauth2

我使用passport-google-oauth20作为我的应用程序的唯一身份验证形式。一切似乎都很好,我可以使用verify回调护照提供的身份验证用户身份并将其存储在数据库中。

在此应用中,我将仅使用google来验证用户身份,并检查该用户是否存在于数据库中。我不会向Google发出更多请求,也不会从Google那里获取更多信息。

我注意到护照回调函数背后发生了很多魔术。我对serializeUserdeserializeUser的工作方式了解不清楚,但是不确定何时是必要的。

护照提供的回调函数会在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('/');
    }
);

我能够获取个人资料和所有我需要的信息。我还需要序列化用户吗?

1 个答案:

答案 0 :(得分:0)

serializeUser和deserializerUserUser函数用于设置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))
        }
     })   
}))

一旦password.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)
    })
})