[Java] AWS Cognito のユーザーリストを取得する方法
AWS CognitoIdentityProvider を使ってユーザーリストを取得。 AWS には何かと制限値が設けられているが、Cognito も例外ではなく、場面によっては工夫が必要になりそう。
環境
AWS SDK for Java V2
Gradle プロジェクト
dependencies {
implementation platform('software.amazon.awssdk:bom:2.16.60')
implementation group: 'software.amazon.awssdk', name: 'cognitoidentityprovider'
...
}
ListUsers
Amazon Cognito User Pool の全ユーザーを取得する方法。ListUsers を使う。
public List<UserType> getListUsers() {
List<UserType> users = new ArrayList<>();
getListUsers(null, users);
return users;
}
List<UserType> getListUsers(String paginationToken, List<UserType> users) {
// リクエスト生成
ListUsersRequest request;
if (paginationToken == null) {
request = ListUsersRequest.builder().userPoolId("USERPOOL_ID").build();
} else {
request = ListUsersRequest.builder().userPoolId("USERPOOL_ID").paginationToken(paginationToken).build();
}
// レスポンス取得
ListUsersResponse response = cognitoIdentityProvider.listUsers(request);
// 結果を格納
users.addAll(response.users());
if (response.paginationToken() != null) {
return getListUsers(response.paginationToken(), users);
} else {
return users;
}
}
1 回のリクエストにつき 60 件しか結果が返ってこない。
Identity pools (federated users) resource quotas
https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html#operation-quotas
Maximum number of results from a single list or lookup call 60
レスポンスには、 PaginationToken
というパラメータが含まれていて、 PaginationToken
でリストに続きがあるかどうかを判断できる。全件取得するには、 PaginationToken
を使って再帰処理する。
ただし、ListUsers
, ListUsersInGroup
は、30 リクエスト/秒の制限がある。リクエスト数が制限値を超えると TooManyRequestsException
が発生する。
そのため、 1 秒あたり取得できる最大ユーザー数は 60 ユーザー/ リクエスト × 30 リクエスト/秒 = 1800 ユーザー/秒 となる。それ以上のユーザー取得が必要な場合には、 sleep
しながらリクエスト送信するとか、後述するグルーピングなどの工夫が必要になる。
ListUsersInGroup
グループを指定して、グループの全ユーザーを取得する方法。 ListUsersInGroup を使う。
ユーザーは事前にグループに追加しておく。
public List<UserType> getListUsersInGroup(String groupName) {
List<UserType> users = new ArrayList<>();
getListUsersInGroup(groupName, null, users);
return users;
}
List<UserType> getListUsersInGroup(String groupName, String nextToken, List<UserType> users) {
// リクエスト生成
ListUsersInGroupRequest request;
if (paginationToken == null) {
request = ListUsersInGroupRequest.builder().userPoolId("USERPOOL_ID").groupName(groupName).build();
} else {
request = ListUsersInGroupRequest.builder().userPoolId("USERPOOL_ID").groupName(groupName).nextToken(nextToken).build();
}
// レスポンス取得
ListUsersInGroupResponse response = cognitoIdentityProvider.listUsersInGroup(request);
// 結果を格納
users.addAll(response.users());
if (response.nextToken() != null) {
return getListUsersInGroup(groupName, response.nextToken(), users);
} else {
return users;
}
}
さいごに
AWS Cognito Pool から、1 度にたくさんのデータを取ってこようとしない方がいい。