如何在Alexa开发者控制台配置账户关联后于Lambda函数获取Google OAuth刷新令牌
获取Alexa Skill中的Google OAuth Refresh Token
要在你的Lambda函数中拿到Google的refresh token,核心是要确保Google OAuth配置和Alexa账户关联设置同时开启离线访问权限,并且让用户完成完整的重新授权流程。下面是一步步的解决方法:
1. 配置Google OAuth客户端以允许离线访问
- 登录Google Cloud Console,找到你的OAuth 2.0客户端ID配置页面
- 在「授权类型」部分,确保勾选了**"offline access"**(这是Google返回refresh token的前提,只有请求离线访问权限时才会生成refresh token)
- 保存配置
2. 更新Alexa开发者控制台的账户关联设置
- 打开你的Alexa技能开发者控制台,进入「账户关联」页面
- 在「授权范围(Scopes)」区域,添加Google的
offline_accessscope(和你现有的权限放在一起,比如:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/offline_access) - 如果你用的是Authorization Code Grant流程(Alexa推荐的账户关联方式),找到「高级设置」,开启**"Allow Alexa to send refresh tokens to your skill"**选项——这一步是关键,否则Alexa不会把refresh token传递到你的Lambda请求中
- 保存所有设置
3. 强制用户完成重新授权流程
因为之前的授权没有包含offline_access scope,旧的授权不会自动生成refresh token,必须让用户重新授权:
- 让用户登录自己的Google账号,进入「安全」→「第三方应用访问权限」,找到你的Alexa技能并移除授权
- 让用户在Alexa配套应用中禁用并重新启用你的技能,或者在Alexa开发者控制台的模拟器中触发Link Account流程,重新完成整个授权步骤
4. 在Lambda函数中获取Refresh Token
完成以上配置后,refresh token会出现在handlerInput.requestEnvelope.context.System.user.refreshToken字段中。你可以在代码中这样处理:
async handle(handlerInput) { console.log('LAUNCH REQUEST CALLED'); const user = handlerInput.requestEnvelope.context.System.user; // 检查access token和refresh token if (!user.accessToken) { console.log('ACCESS TOKEN NOT FOUND IN LAUNCH REQUEST'); return handlerInput.responseBuilder .speak("Please link your account first.") .reprompt("Please link your account first.") .withLinkAccountCard() .withShouldEndSession(true) .getResponse(); } // 获取refresh token(如果存在) const refreshToken = user.refreshToken; if (refreshToken) { console.log('Refresh token found'); // 注意:不要在生产环境打印完整refresh token,避免安全风险 } else { console.log('Refresh token not found - make sure offline_access is configured and user re-authorized'); } // 后续的Google API授权逻辑 const { google } = require('googleapis'); const SCOPES = [ 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/tasks.readonly', 'https://www.googleapis.com/auth/tasks', 'https://www.googleapis.com/auth/offline_access' // 别忘了加上这个scope ]; function authorize() { return new Promise((resolve) => { const oAuth2Client = new google.auth.OAuth2( process.env.client_id, process.env.client_secret, process.env.redirect_uri // 建议用环境变量存储,不要硬编码 ); // 同时设置access token和refresh token oAuth2Client.credentials = { "access_token": user.accessToken, "refresh_token": refreshToken }; resolve(oAuth2Client); }); } // 继续你的业务逻辑... const speechText = 'Welcome!'; return handlerInput.responseBuilder .speak(speechText) .reprompt(speechText) .getResponse(); }
关键注意事项
offline_accessscope必须同时在Google OAuth和Alexa账户关联中配置,缺一不可- Refresh token只会在第一次授权或重新授权时返回,所以必须确保用户完成了完整的重新授权流程
- 不要在日志中打印完整的refresh token,避免泄露敏感信息
内容的提问来源于stack exchange,提问作者Raghavendra
相关产品推荐
相关产品推荐

