如何传入Cognito机密客户端凭证创建boto3 cognito-idp客户端
- 已创建AWS Cognito用户池
- 为该用户池创建2个应用客户端:第一个为public client(公开客户端)(供前端使用),第二个为confidential client(机密客户端)(供后端使用)
- 已开发基于React的前端接入AWS Cognito,前端会将idToken传递给服务端
- 服务端可正常验证idToken,并能从idToken中提取用户名
调用CognitoIdentityProvider.Client.admin_update_user_attributes接口更新用户属性时收到报错:The security token included in the request is invalid.
错误实现为初始化boto3客户端时,将Cognito机密应用客户端的app client id和app client secret分别作为aws_access_key_id和aws_secret_access_key传入,参考代码:
import boto3 user_pool_id = "xxx" client = boto3.client( 'cognito-idp', aws_access_key_id="xxx", aws_secret_access_key="xxx", region_name='xxx' ) print(client.admin_get_user( UserPoolId="xxx", Username="xxx" ))
运行抛出异常:
botocore.exceptions.ClientError: An error occurred (UnrecognizedClientException) when calling the ListUsers operation: The security token included in the request is invalid.
Cognito应用客户端的ID和密钥不属于AWS IAM身份凭证,不能直接传入aws_access_key_id和aws_secret_access_key参数。这两个参数仅接受IAM用户/角色对应的访问密钥,传入Cognito客户端凭证会直接触发无效令牌报错。
根据你的使用场景二选一即可:
需要调用Admin前缀接口的场景
所有带Admin前缀的Cognito接口(包括admin_update_user_attributes、admin_get_user),都要求调用方持有对应权限的IAM凭证,和Cognito应用客户端的密钥无关:- 本地调试:给你的IAM用户配置Cognito对应操作的权限(可直接附加
AmazonCognitoPowerUserAccess托管策略,生产环境建议配置最小自定义权限),使用该IAM用户的访问密钥初始化客户端 - 线上部署:给运行代码的AWS资源(EC2、ECS、Lambda等)绑定对应权限的IAM角色,boto3会自动获取临时安全凭证,不需要硬编码传入密钥
最小权限参考策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cognito-idp:AdminUpdateUserAttributes", "cognito-idp:AdminGetUser" ], "Resource": "arn:aws:cognito-idp:你的区域:你的账号ID:userpool/你的用户池ID" } ] }正确初始化示例(线上绑定角色后无需传密钥):
import boto3 client = boto3.client('cognito-idp', region_name='你的区域')- 本地调试:给你的IAM用户配置Cognito对应操作的权限(可直接附加
不需要管理员权限的场景
如果你不想配置IAM凭证,可以放弃调用Admin前缀接口,改用用户侧接口update_user_attributes,调用时传入前端返回给后端的用户有效AccessToken即可,该接口仅校验用户自身令牌,不需要IAM权限,也不需要传入Cognito客户端密钥。
注意:Cognito机密客户端的ID和密钥仅用于调用用户侧公开接口(比如
initiate_auth发起登录认证)时做客户端身份校验,既不能作为IAM凭证调用AWS服务接口,也不能用来调用Admin级别的Cognito管理接口。
内容的提问来源于stack exchange,提问作者user2301346

