使用 Google 的 Node js Express Passport 身份验证 Oath2 会话覆盖会话

问题描述 投票:0回答:1

Google 建议在首次注册用户时要求用户提供最少的权限,然后在用户需要时要求扩展这些权限。 因此,我一开始就使用基于令牌的身份验证,但如果用户想要在我的网站上执行某些功能,他们将需要授予应用程序特定的驱动器权限。 许多用户永远不会需要这个,所以我真的倾向于同意谷歌,只在需要时询问那些需要它的人。 所以,我继续执行这段代码来做到这一点:


app.use(session({
  secret: vars.SESSIONSECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    sameSite: true,
    secure: true,
    httpOnly: true,
    maxAge: 86400000 // 1 day in milliseconds
  },
  store: new RedisStore({ client: redisClient }),
}));
const extendedGoogleStrategy = new GoogleStrategy(
    {
        clientID: vars.CLIENTID,
        clientSecret: vars.CLIENTSECRET,
        callbackURL: vars.EXTENDCALLBACKURL,
        scope: ['openid', 'profile', 'email', 'https://www.googleapis.com/auth/drive.file'],
        accessType: 'offline', // Request a refresh token
        prompt: 'consent', // Show consent screen for refresh token
        display: 'popup',
        authorizationParams: function () {
            return {
                include_granted_scopes: true,
            };
        },
        failureRedirect: '/oops',
        passReqToCallback: true, // Pass the request object to the callback
    },
    (req, accessToken, refreshToken, profile, done) => {
        // Now we have the access token, you can use it to make authorized API requests
        // save that access token and refresh token to profile and send it back to the callback
        // so they can be processed in the session and user db space
        dp.debugPrint(["Google Strategy accessToken"], dp.DEBUG_LEVEL.MEDIUM);
        profile.accessToken = accessToken;
        profile.refreshToken = refreshToken;
        profile.googleDriveEnabled = true;
        return done(null, profile);
    } 

app.use(passport.initialize());
app.use(passport.session());
passport.use('googleExtended', authentication.extendedGoogleStrategy);
// Google OAuth2 authentication routes
router.get('/google/extend-scope',
  (req, res, next) => {
  // Redirect the user to initiate authentication with the new scope
  passport.authenticate('googleExtended', {
    scope: ['openid', 'profile', 'email', 'https://www.googleapis.com/auth/drive.file'],
    accessType: 'offline', // Add this line
    prompt: 'consent', // Add this line
    display: 'popup',
    authorizationParams: function () {
      return {
        include_granted_scopes: true,
      };
    },
   failureRedirect: '/oops',
   keepSessionInfo: true

  })(req, res, next);
});

router.get('/google/extend-scope/callback',
    passport.authenticate('googleExtended', {
        failureRedirect: '/oops',
        keepSessionInfo: true
    }),
    async (req, res) => {
        //... store new accessToken in the session and store the renewToken in the user account db ...
});

代码似乎有效,直到我发现我的会话在某种程度上被覆盖了(一度设置 session: false 似乎解决了问题,但那是在我通过启动基于令牌的身份验证代码与 oath2 进行重构之前 - a长话短说为什么我改变了它但我做到了)。 也许其他东西发生了变化,或者它从来没有正常工作过,但我没有依赖关系,不会受到会话被覆盖的影响,直到后来。 不管怎样,我的会话被覆盖了。

keepSessionInfo: true

(护照 0.6.0 中引入的一项未记录的功能 - 这总是让我使用起来感到紧张)应该可以防止这种情况,但事实并非如此。 我已经在 git 存储库上发布了一张票证,但这让我开始思考。

A)有人遇到过此会话覆盖问题吗?如果是,解决方法是什么?

B)我是否以正确的方式处理这个问题? 如果是的话,我应该怎么做才能最好地保护刷新令牌(是的,谷歌对此有一些措辞,但我认为最好寻求一些建议)

C) 这个流程似乎不断询问权限,这正常吗? 我仍然处于开发模式,所以我明白它警告应用程序正在开发而不是生产,但是天啊,除此之外还有很多确认)

我希望扩展用户授予谷歌的权限以包括谷歌驱动器。 我期望获得 accessToken 和 renewToken,我期望能够将它们存储在用户会话/数据库中(分别)。 我获得了延期拨款,但会话被新会话覆盖,缺少会话中的其他数据,我对存储到非会话数据库进行检索不感兴趣。 (它是状态信息,不适合存储在会话存储之外)

node.js session google-drive-api passport.js
1个回答
0
投票

很抱歉您从未得到答案,但您的问题为我解决了这个问题。

keepSessionInfo:true

从 google Oauth 返回后会话被清除和保留之间存在差异。

+-- [电子邮件受保护] `-- [电子邮件受保护]

© www.soinside.com 2019 - 2024. All rights reserved.