6

我正在尝试在我的 node + nestjs api 中对用户进行身份验证,并希望提示用户选择一个帐户。

如果您只有 1 个帐户登录,则提示不会显示,即使您使用 2 个帐户登录并收到提示,重定向中的 URL 参数中仍然有 &prompt=none。

事实上,我可以确认提示选项没有任何区别。

我的代码简化如下:

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

我怎么可能进一步调试它以查看引擎盖下为什么/发生了什么?

实际端点:


@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,
    });
  }
}

我无法使用任何警卫或 UseGuards 装饰器传递选项对象。

我还尝试将一个额外的对象参数传递给超级调用,但这也不起作用。

4

2 回答 2

4

Sebastian 我已经处理这个问题大约一个星期了。我终于找到了问题所在,然后发现有一篇非常相似的 Stack Overflow 文章也有同样的问题:

使用passport-google-oauth20时自动登录

当您OAuth2Strategy使用选项初始化类时,问题就出现了。它不会将其选项传递给passport.authenticate(passport, name, options, callback)调用,因为passport.authenticate(...)仅在您为路由注册中间件处理程序时才会调用。

因此在注册路由中间件prompt: 'select_account'时需要通过passport.authenticate()

像这样:

router.get(
    '/auth/google',
    passport.authenticate('google', {
        accessType: 'offline',
        callbackURL: callbackUrl,
        includeGrantedScopes: true,
        scope: ['profile', 'email'],
        prompt: 'select_account', // <=== Add your prompt setting here
    })
);
于 2020-07-22T21:07:18.617 回答
2

对于任何使用nestjs并面临同样问题的人,这里是解决方案

    class AuthGoogle extends AuthGuard('google') {
        constructor() {
            super({
                prompt: 'select_account'
            });
        } }
    }
     // using
    @UseGuards(AuthGoogle)
    private googleAuth() {}
于 2020-10-16T04:04:15.480 回答