无AWS_KEY_ID和AWS_SECRET_KEY能否获取AWS Cognito用户详情
仅持有Cognito用户池ID、应用客户端ID、客户端密钥的前提下,无法直接拉取用户池内的全量用户详情与用户名列表。
核心原因
Cognito的ListUsers等拉取全量用户的接口属于管理员级服务端API,调用必须携带拥有cognito-idp:ListUsers权限的IAM身份凭证(即你提到的AWS_KEY_ID/AWS_SECRET_KEY,或是绑定了对应权限的IAM角色临时凭证)。
你当前持有的客户端ID、客户端密钥仅能用于终端用户侧的注册、登录、token刷新、密码修改等用户自助操作,Cognito默认不会给这类客户端开放全量用户查询权限——如果客户端凭证能拉取全量用户,任何拿到客户端信息的人都可以拖走整个用户池的数据,属于明确的安全设计。
可行实现方案
方案1(适合需要实时拉取Cognito最新数据的场景)
申请对应Cognito用户池的只读IAM权限:如果你的PHP服务部署在AWS生态(EC2/ECS/EKS/Lambda等),直接给运行环境绑定附带cognito-idp:ListUsers权限的IAM角色即可,不需要硬编码密钥,PHP SDK会自动读取环境内的角色凭证;如果是部署在非AWS环境,再申请对应权限的IAM用户AK/SK配置到服务端环境变量即可。
分页拉取全量用户的PHP示例代码:<?php require 'vendor/autoload.php'; use Aws\CognitoIdentityProvider\CognitoIdentityProviderClient; use Aws\Exception\AwsException; $cognitoClient = new CognitoIdentityProviderClient([ 'version' => 'latest', 'region' => '替换为你的Cognito用户池所在区域,例如ap-southeast-1' // 绑定IAM角色时无需手动传credentials配置,SDK会自动获取凭证 // 非AWS环境可通过环境变量传递AK/SK,不要硬编码在代码里 ]); $userList = []; $pageToken = null; do { $requestParams = [ 'UserPoolId' => '替换为你的用户池ID', 'Limit' => 60, // ListUsers接口单次拉取上限为60条 ]; if ($pageToken) { $requestParams['PaginationToken'] = $pageToken; } try { $response = $cognitoClient->listUsers($requestParams); $userList = array_merge($userList, $response['Users']); $pageToken = $response['PaginationToken'] ?? null; } catch (AwsException $e) { error_log("拉取Cognito用户失败: " . $e->getMessage()); break; } } while ($pageToken); // 遍历$userList即可拿到每个用户的Username、用户属性、创建时间等信息方案2(生产环境更推荐的方案)
不要实时调用Cognito接口拉取用户列表,新增用户信息同步逻辑:当用户首次通过Cognito注册、首次登录时,在服务端验证ID Token合法后,把对应用户的用户名、sub、邮箱等你需要的信息存入自有业务数据库。后续网站端需要展示用户列表时,直接查询自有数据库即可。
这个方案不需要持有Cognito管理员权限,查询速度远快于调用Cognito API,还可以灵活支持搜索、分页、用户状态标记等定制化需求,也避免了频繁调用Cognito API产生的额外费用。
注意事项
不要尝试给Cognito应用客户端附加管理员权限,也绝对不要把IAM AK/SK、Cognito客户端密钥泄露到前端代码或公开可访问的位置,否则会导致整个用户池数据泄露、被恶意篡改的风险。
内容的提问来源于stack exchange,提问作者Developer trainee

