从AWS Cognito用户池获取用户信息遇权限异常求助
问题描述
使用Ruby版AWS SDK的Aws::CognitoIdentityProvider::Client调用get_user接口时,触发NotAuthorizedException异常,先后遇到"无效访问令牌"和"访问令牌缺少必要权限范围"两种错误。
技术栈
Angular、Ruby、Ruby版AWS SDK、Lambda函数、带托管UI的Cognito用户池
Cognito用户属性字段
["name", "given_name", "family_name", "middle_name", "nickname", "preferred_username", "profile", "picture", "website", "email", "email_verified", "gender", "birthdate", "zoneinfo", "locale", "phone_number", "phone_number_verified", "address", "updated_at", "custom:pincode", "cognito:mfa_enabled", "cognito:username"]
操作流程
Angular端使用授权链接完成注册登录并获取授权码:
https://auth1.blah.in/oauth2/authorize?response_type=code&client_id=xxxxxxxxxxxxxxxxxxxxxx&redirect_uri=http://localhost:4200/callbackRuby端调用
get_user接口获取用户信息,代码如下:require 'json' require 'aws-sdk-cognitoidentityprovider' client = Aws::CognitoIdentityProvider::Client.new( region: "us-east-1" ) resp = client.get_user({ access_token: "yyyyyyyy-8d77-zzzz-92e1-xxxxxxx", })触发错误:
call': Invalid Access Token (Aws::CognitoIdentityProvider::Errors::NotAuthorizedException)为授权链接添加scope参数后,链接变为:
https://auth1.blah.in/oauth2/authorize?response_type=code&client_id=xxxxxxxxxxxxxxxxxxxxxx&redirect_uri=http://localhost:4200/callback&state=STATE&scope=phone+openid+profile+aws.cognito.signin.user.admin&identity_provider=COGNITO但Cognito托管UI无法打开,返回错误:
http://localhost:4200/callback?error_description=invalid_scope&state=STATE&error=invalid_request
更新内容(2023-07-17)
通过授权码调用token接口生成access_token,请求命令如下:
curl --request POST --location 'https://auth1.blah.in/oauth2/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Authorization: Basic longgggggblahblahblah==' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'code=xxxxxxxx-a80e-yyyyyy-a5f6-zzzzzzzz' \ --data-urlencode 'redirect_uri=http://localhost:4200/callback'
获取到access_token后再次调用get_user,仍触发错误:NotAuthorizedException (Access Token does not have required scopes)
疑问
- 当前实现方式是否正确?若错误请指导(本人为Cognito新手)
- 授权链接中的Scope具体是什么?
解决方案与说明
1. 实现方式修正
你的流程方向正确,但权限范围(Scope)配置和令牌使用存在问题:
- 无Scope的授权码问题:未指定Scope时获取的access_token仅包含基础权限,没有调用
get_user所需的权限,因此触发异常。 - invalid_scope报错原因:
aws.cognito.signin.user.admin是Cognito特殊权限,需要先在用户池应用客户端中开启"自定义OAuth范围"并添加该范围;phone、profile等标准Scope需要在用户池属性设置中开启对应属性,同时在应用客户端的"允许OAuth范围"里勾选。
正确操作步骤:
- 登录AWS控制台进入目标Cognito用户池:
- 进入应用客户端,编辑目标客户端的"应用客户端设置":
- 在"允许OAuth范围"中勾选
openid、profile、phone(按需选择);若需使用aws.cognito.signin.user.admin,先在"启用自定义OAuth范围"中添加该范围,再勾选。 - 确保"授权码授予"已勾选(匹配你的
response_type=code模式)。
- 在"允许OAuth范围"中勾选
- 进入属性页面,确保需要获取的用户属性(如name、phone)已设置为可读写/只读,且在应用客户端的"允许的属性"中已勾选。
- 进入应用客户端,编辑目标客户端的"应用客户端设置":
- 使用配置好的有效Scope生成授权链接:
(若已配置https://auth1.blah.in/oauth2/authorize?response_type=code&client_id=xxxxxxxxxxxxxxxxxxxxxx&redirect_uri=http://localhost:4200/callback&state=STATE&scope=openid+profile+phoneaws.cognito.signin.user.admin,可追加到Scope中) - 用新授权码获取access_token,此时令牌会包含所需权限,再调用
get_user即可正常执行。
2. Scope含义说明
Scope是OAuth2/OpenID Connect中的权限范围,用于限制令牌可访问的资源和接口:
- 标准OpenID Scope:
openid:必填项,用于获取ID令牌以标识用户身份。profile:允许访问用户基础资料属性(如name、given_name等)。phone:允许访问用户电话号码属性。
- Cognito自定义Scope:
aws.cognito.signin.user.admin:允许令牌调用Cognito用户池管理接口(如get_user、update_user_attributes等),需额外配置才能启用。
内容的提问来源于stack exchange,提问作者Jigish Thakar

