如何通过Cognito身份池获取临时AWS凭证?非SDK方式遇400错误求助
我来帮你捋捋这个400错误的排查方向——手动调用AWS API确实容易在细节上踩坑,尤其是不用SDK的情况下:
请求格式错误(最可能的核心原因)
Cognito的GetCredentialsForIdentity接口要求请求体必须是JSON格式,但你的代码里直接用data=body传字典,requests会默认把它编码成application/x-www-form-urlencoded格式,完全不符合接口要求。你需要:- 在headers里添加
Content-Type: application/json - 用
json=body参数代替data=body(requests会自动序列化字典为JSON并设置Content-Type),或者手动用json.dumps(body)序列化后传给data并显式设置Content-Type。
- 在headers里添加
X-Amz-Date过期
你代码里用的是固定的20151020T232759Z,这个日期早就过期了。AWS要求这个头必须是当前的UTC时间,格式为YYYYMMDDTHHMMSSZ。你可以用Python的datetime模块生成实时的时间字符串:datetime.datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')IdentityId有效性问题
确认你填的IdentityId是对应us-east-1区域Cognito Identity Pool的有效ID,检查是否有拼写错误(比如冒号前后的字符、区域前缀是否匹配)。如果是通过认证流程获取的IdentityId,还要确保它没有过期或被撤销。认证信息缺失(针对已认证身份)
如果这个IdentityId是绑定了用户身份(比如Cognito User Pool、Google/Facebook登录)的,调用GetCredentialsForIdentity时必须在请求体里添加Logins字段,包含对应的身份提供商令牌。比如:"Logins": { "cognito-idp.us-east-1.amazonaws.com/us-east-1_XXXXXX": "用户的ID Token" }这种情况下,请求还需要符合AWS Signature Version 4的签名规范,否则也会报400或403错误。
查看具体错误信息
不要只打印response对象,打印response.text看看AWS返回的详细错误内容——AWS的400响应里会明确告诉你是参数错误、签名问题还是其他原因,比如InvalidParameterException、MissingAuthenticationToken等,这能帮你快速定位核心问题。
修正后的测试代码示例
import requests import datetime url = 'https://cognito-identity.us-east-1.amazonaws.com' headers = { 'X-AMZ-TARGET': 'com.amazonaws.cognito.identity.model.AWSCognitoIdentityService.GetCredentialsForIdentity', 'X-AMZ-DATE': datetime.datetime.utcnow().strftime('%Y%m%dT%H%M%SZ'), 'Content-Type': 'application/json' } body = { 'IdentityId': 'us-east-1:123456789' } # 如果是已认证身份,取消下面注释并填写正确的Logins信息 # body['Logins'] = { # 'cognito-idp.us-east-1.amazonaws.com/你的UserPoolID': '用户的ID Token' # } response = requests.post(url=url, json=body, headers=headers) print(response.status_code) print(response.text)
内容的提问来源于stack exchange,提问作者ColossalBoar

