Google OAuth2.0授权码交换时部分白名单邮箱无法获取id_token
Google OAuth 2.0部分白名单邮箱无法获取id_token问题
问题背景
应用未通过Google验证,仅开放白名单邮箱使用OAuth流程。个人邮箱测试时可正常获取id_token,但白名单内的朋友邮箱交换授权码时,仅返回access_token、refresh_token、scope、token_type和expiry_date,无id_token且无任何报错。
代码示例
class GoogleOauthService implements GoogleOauth { #client; constructor() { this.#client = new google.auth.OAuth2( process.env.GOOGLE_CLIENT_ID, process.env.GOOGLE_CLIENT_SECRET, process.env.GOOGLE_REDIRECT_URL ); } async getTokens( params: GoogleOauth.GetTokensParams ): GoogleOauth.GetTokensResult { const { tokens } = await this.#client.getToken(params.code); return { accessToken: tokens.access_token, refreshToken: tokens.refresh_token, scope: tokens.scope, tokenType: tokens.token_type, idToken: tokens.id_token, expiryDate: tokens.expiry_date, }; } }
错误返回示例
{ access_token: 'secret access token', refresh_token: 'secret refresh token', scope: 'https://www.googleapis.com/auth/calendar', token_type: 'Bearer', expiry_date: 1673742003175 }
原因分析与解决方案
核心原因
id_token是OpenID Connect(OIDC)流程的专属返回值,必须满足两个条件才会返回:
- 授权请求中必须包含
openidscope(通常搭配email或profilescope) - 授权流程需符合OIDC规范
你当前返回的scope仅包含日历权限,说明授权请求时未添加OIDC相关scope。个人邮箱能拿到id_token属于特例(可能是开发者账号的默认授权缓存、或之前测试过OIDC流程留下的记录),不代表正常逻辑。
解决方案
修改授权URL的scope配置
在生成授权URL时,必须加入openid及相关OIDC scope,示例代码如下:// 生成授权URL的逻辑(需补充到你的服务类中) generateAuthUrl(): string { return this.#client.generateAuthUrl({ access_type: 'offline', // 加入openid、email,搭配原有日历scope scope: ['openid', 'email', 'https://www.googleapis.com/auth/calendar'], }); }重新发起授权流程
让测试的朋友清除Google账号对该应用的授权记录(Google账号设置→安全→第三方应用访问→找到你的应用并移除),然后重新走授权流程,再交换token即可获取id_token。
内容的提问来源于stack exchange,提问作者kylejw2
相关产品推荐
相关产品推荐

