如何用Google Access Token换取ID Token或获取Cognito身份ID?
解决Google Access Token换取Cognito身份ID的问题
首先直接回应你的核心疑问:Google本身不支持用Access Token换取ID Token——这两种令牌的设计目标完全不同:Access Token是用来授权访问Google API的凭证,而ID Token是OIDC体系中用来验证用户身份的令牌,二者无法直接互相转换。不过不用担心,我们有可行方案绕开这个限制,用Google Access Token获取Cognito身份ID,同时解决Alexa无法传递ID Token的问题。
一、用Google Access Token获取Cognito身份ID的可行方案
你可以通过Cognito身份池的自定义身份验证流程实现,核心逻辑是在Lambda里先验证Google Access Token的合法性,再让Cognito信任这个验证结果,返回对应的身份ID。具体步骤如下:
1. 配置Cognito身份池的自定义身份提供者
- 登录AWS控制台,进入目标Cognito身份池,找到「身份验证提供者」选项卡,选择「自定义」
- 为你的自定义提供者设置一个唯一名称(比如
google-custom-auth),这个名称后续会在代码中用到
2. 在Lambda中实现令牌验证与Cognito身份ID获取
Lambda逻辑分为两步:先验证Google Access Token有效,再调用Cognito的GetId API获取身份ID。以下是Python示例代码:
import boto3 import requests def lambda_handler(event, context): # 从Alexa事件中提取Google Access Token try: google_access_token = event["session"]["user"]["accessToken"] except KeyError: return {"error": "Missing Google Access Token from Alexa request"} # 第一步:验证Google Access Token的有效性 token_verify_url = "https://oauth2.googleapis.com/tokeninfo" verify_response = requests.get(token_verify_url, params={"access_token": google_access_token}) if verify_response.status_code != 200: return {"error": "Invalid or expired Google Access Token"} user_info = verify_response.json() # 获取Google用户的全局唯一标识(sub字段) google_user_id = user_info["sub"] # 第二步:调用Cognito GetId获取身份ID cognito_client = boto3.client("cognito-identity") try: cognito_response = cognito_client.get_id( IdentityPoolId="YOUR_IDENTITY_POOL_ID", # 替换成你的身份池ID Logins={ # 使用自定义身份提供者的名称作为键,用户唯一标识作为值 "google-custom-auth": google_user_id } ) return {"cognito_identity_id": cognito_response["IdentityId"]} except Exception as e: return {"error": f"Failed to get Cognito ID: {str(e)}"}
3. 关键注意事项
- 验证令牌时,建议额外检查返回的
exp(过期时间)字段,避免使用已过期的令牌 - 自定义身份提供者的核心是让Cognito信任你对用户身份的验证,所以必须确保令牌验证逻辑足够严谨,防止身份伪造
二、关于Alexa无法传递ID Token的问题
你提到无法配置Alexa传递ID Token,这是很常见的情况——Alexa在账户关联后通常只会返回Access Token。不过上面的方案已经完美解决了这个问题:不需要Alexa传递ID Token,所有身份验证和Cognito身份ID获取逻辑都在Lambda内部完成,Alexa只需要把Google Access Token传给Lambda即可。
替代方案:使用Cognito用户池的自定义认证
如果你使用的是Cognito用户池而非身份池,也可以通过自定义认证流程实现:
- 在用户池的「认证流程」中启用自定义认证
- 创建一个Lambda触发器(自定义认证挑战),在其中验证Google Access Token的有效性
- 验证通过后,生成Cognito的ID Token和Access Token,后续即可用这些令牌获取用户身份信息
内容的提问来源于stack exchange,提问作者Panda
相关产品推荐
相关产品推荐

