如何在NodeJS中从Google API的oAuth2Client获取sub或id_token
解决OAuth2Client无法获取id_token及关联Google账户的问题
问题根源
你当前的授权流程缺少OpenID Connect相关配置,导致Google不会返回包含sub(用户唯一标识)的id_token,同时未调用setCredentials方法导致oAuth2Client.credentials为空。
具体修复步骤
1. 添加OpenID Connect权限范围
发起OAuth授权请求时,必须包含openid scope(这是获取id_token的必要条件),可同时搭配email或profile获取更多用户信息。示例scope配置:
const scopes = [ 'https://www.googleapis.com/auth/analytics.readonly', // GA访问权限 'openid', // 必须添加,用于获取id_token 'email' // 可选,获取用户邮箱 ];
2. 生成包含id_token的授权URL
生成授权链接时,确保响应类型包含id_token(包含openid scope时googleapis会自动处理,也可显式指定),同时保留access_type: 'offline'以获取refresh_token:
const authUrl = oAuth2Client.generateAuthUrl({ access_type: 'offline', scope: scopes, response_type: 'code id_token' // 显式指定返回code和id_token });
3. 正确设置凭证并解析id_token
用授权code交换token后,必须调用setCredentials将token存入客户端实例,之后即可从返回的tokens中取出id_token并解析得到sub:
import { google } from 'googleapis'; import { OAuth2Client } from 'google-auth-library'; const oAuth2Client = new OAuth2Client(client_id, client_secret, redirect_uri); const tokenRes = await oAuth2Client.getToken(code); // 关键:将获取到的token设置到客户端实例中 oAuth2Client.setCredentials(tokenRes.tokens); // 解析id_token获取用户唯一标识sub if (tokenRes.tokens.id_token) { const ticket = await oAuth2Client.verifyIdToken({ idToken: tokenRes.tokens.id_token, audience: client_id // 替换为你的OAuth客户端ID }); const payload = ticket.getPayload(); const googleUserId = payload.sub; // 这就是Google账户的永久唯一标识 console.log('Google账户ID:', googleUserId); } // 现在credentials不再为空 console.log(JSON.stringify(oAuth2Client.credentials));
额外注意事项
- 如果用户之前已授权过旧的scope列表,需强制重新授权才能获取id_token,可在
generateAuthUrl中添加prompt: 'consent'参数。 sub是Google账户的永久唯一标识,不会随用户新增/删除GA属性而变化,适合用来将refresh_token与用户账户绑定。
内容的提问来源于stack exchange,提问作者Matthew Michaud
相关产品推荐
相关产品推荐

