服务账号Google Auth Token异常:Node.js生成的AccessToken无法调用API
问题分析与解决
你的核心问题是域范围委派的服务账号获取AccessToken时,没有指定要模拟的域内用户邮箱,这是这类场景下必须的参数——和Token显示的省略号无关(省略号只是输出时的自动截断,实际返回的Token是完整的)。
关键修复点
在生成JWT的payload中添加sub字段,值为你需要模拟的域内用户邮箱(该用户需具备Google Ads的访问权限)。没有这个字段,服务账号无法以域内用户身份发起API请求,自然会导致Token无效。
修正后的完整代码
const jwt = require("jsonwebtoken"); const axios = require("axios"); const sa = require("./credentials-ads.json"); const authUrl = "https://www.googleapis.com/oauth2/v4/token"; const scope = "https://www.googleapis.com/auth/adwords"; // 替换为你要模拟的域内用户邮箱 const impersonatedUser = "user@your-domain.com"; const getSignedJwt = () => { const token = { iss: sa.client_email, iat: parseInt(Date.now() / 1000), exp: parseInt(Date.now() / 1000) + 60 * 60, // 60分钟有效期 aud: authUrl, scope, sub: impersonatedUser // 新增:指定要模拟的用户 }; return jwt.sign(token, sa.private_key, { algorithm: "RS256" }); }; // 包裹在async函数中执行 async function getAccessToken() { try { const signedJwt = getSignedJwt(); const google_token = await axios.post( 'https://oauth2.googleapis.com/token', `grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=${signedJwt}`, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ); console.log(google_token.data); return google_token.data; } catch (error) { console.error("获取Token失败:", error.response?.data || error.message); } } // 调用函数 getAccessToken();
额外检查项
- 确认你的服务账号已在Google Workspace管理控制台中启用域范围委派。
- 确认已在管理控制台中为该服务账号授权了
https://www.googleapis.com/auth/adwords权限范围。 - 确保
impersonatedUser对应的用户确实拥有Google Ads访问权限,且属于你的域内用户。
内容的提问来源于stack exchange,提问作者Noaman Abdul Gaffar
相关产品推荐
相关产品推荐

