简体   繁体   English

当只有1个谷歌账户登录时,护照谷歌Oauth2不提示select账户

[英]Passport Google Oauth2 not prompting select account when only 1 google account logged in

I'm trying to authenticate users in my node + nestjs api and want to prompt the user to select an account.我正在尝试在我的节点 + nestjs api 中对用户进行身份验证,并希望提示用户使用 select 帐户。

The prompt does not show up if you have only 1 account logged in and even when you are logged in with 2 accounts and you get prompted, the URL in the redirect still has &prompt=none in the parameters.如果您只有 1 个帐户登录,则提示不会显示,即使您使用 2 个帐户登录并收到提示,重定向中的 URL 参数中仍然有 &prompt=none。

I can in fact confirm that it makes no difference that prompt option.事实上,我可以确认提示选项没有任何区别。

My code simplified below:我的代码简化如下:

import { OAuth2Strategy } from "passport-google-oauth";
import { PassportStrategy } from "@nestjs/passport";
@Injectable()
export class GoogleStrategy extends PassportStrategy(OAuth2Strategy, "google") {
  constructor(secretsService: SecretsService) {
    super({
      clientID: secretsService.get("google", "clientid"),
      clientSecret: secretsService.get("google", "clientsecret"),
      callbackURL: "https://localhost:3000/auth/google/redirect",
      scope: ["email", "profile", "openid"],
      passReqToCallback: true,
      prompt: "select_account",
    });
  }

  async validate(req: Request, accessToken, refreshToken, profile, done) {
    const { name, emails, photos } = profile;
    const user = {
      email: emails[0].value,
      firstName: name.givenName,
      lastName: name.familyName,
      picture: photos[0].value,
      accessToken,
    };
    return done(null, user);
  }
}

How can i possibly further debug this to see why/whats happening under the hood?我怎么可能进一步调试它以查看引擎盖下为什么/发生了什么?

The actual endpoints:实际端点:


@Controller("auth")
export class AuthController {
  @Get("google")
  @UseGuards(AuthGuard("google"))
  private googleAuth() {}

  @Get("google/redirect")
  @UseGuards(AuthGuard("google"))
  googleAuthRedirect(@Req() req: Request, @Res() res: Response) {
    if (!req.user) {
      return res.send("No user from google");
    }

    return res.send({
      message: "User information from google",
      user: req.user,
    });
  }
}

I can't pass an options object with any of the guards or UseGuards decorator.我无法使用任何警卫或 UseGuards 装饰器传递选项 object。

I've also tried to pass an extra object parameter to the super call but that didn't work either.我还尝试将额外的 object 参数传递给超级调用,但这也不起作用。

Sebastian I've been dealing with this issue as well for about a week. Sebastian 我已经处理这个问题大约一个星期了。 I've finally found what the issue was, and then found that there's a very similar Stack Overflow article that had the same problem:我终于找到了问题所在,然后发现有一篇非常相似的 Stack Overflow 文章也有同样的问题:

Auto login while using passport-google-oauth20 使用passport-google-oauth20时自动登录

The problem comes in when you initialize OAuth2Strategy class with options.当您使用选项初始化OAuth2Strategy class 时,问题就出现了。 It does not pass it's options along to the passport.authenticate(passport, name, options, callback) call since passport.authenticate(...) is only called when you register your middleware handlers for your routes.它不会将其选项传递给passport.authenticate(passport, name, options, callback)调用,因为仅在您为路由注册中间件处理程序时才会调用passport.authenticate(...)

You therefore need to pass prompt: 'select_account' when you register passport.authenticate() route middleware因此,您需要在注册passport.authenticate()路由中间件时通过prompt: 'select_account'

Like so:像这样:

router.get(
    '/auth/google',
    passport.authenticate('google', {
        accessType: 'offline',
        callbackURL: callbackUrl,
        includeGrantedScopes: true,
        scope: ['profile', 'email'],
        prompt: 'select_account', // <=== Add your prompt setting here
    })
);

For anyone use nestjs and facing same issue, here is the solution对于任何使用nestjs并面临同样问题的人,这里是解决方案

    class AuthGoogle extends AuthGuard('google') {
        constructor() {
            super({
                prompt: 'select_account'
            });
        } }
    }
     // using
    @UseGuards(AuthGoogle)
    private googleAuth() {}

Sebastian, you can also do this straight from the strategy class itself instead of making a guard specially for invoking the prompt. Sebastian,您也可以直接从策略 class 本身执行此操作,而不是专门为调用提示制作防护。

Check below.检查下面。

sample code示例代码

Just add this after your constructor call in the strategy class and it will work.只需在策略 class 中的构造函数调用之后添加它,它就会起作用。 You can directly copy the code.可以直接复制代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Passport JS Google OAuth2 - 强制登录或帐户选择器 - Passport JS Google OAuth2 - force login or account chooser 如何更改仅访问我的 Google 帐户的 discord 机器人以准备弃用 OAuth2 OOB? - How do I change a discord bot that accesses only my Google account in prep for OAuth2 OOB deprecation? Google OAuth2服务帐户HTTP / REST身份验证 - Google OAuth2 Service Account HTTP/REST Authentication 尝试使用 Passport 设置 Google OAuth2 时“id”无效 - Invalid "id" when trying to set up Google OAuth2 with Passport 使用Google日历API oauth2服务帐户(node.js)模拟用户 - Impersonate user with google calendar API oauth2 service account (node.js) 将另一个帐户与护照上的 oauth 关联 - Link another account with oauth on passport Node.js + Passport - 使用 Google oauth2 时出现意外重定向 - Node.js + Passport - Unexpected redirect when using Google oauth2 在 Heroku 上实时部署时,passport google oauth2 会导致“内部服务器错误” - passport google oauth2 causes “internal server error” when deployed live on Heroku 从 Google Passport 策略中检索 OAuth2 客户端 - Retrieving OAuth2 Client from Google Passport Strategy 如何访问谷歌 Oauth2 护照中的个人资料信息? - How can I access profile information in google Oauth2 passport?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM