关于 cognito
AWS Cognito 的参考指南,面向配置 Web 和移动应用认证、授权及用户管理的开发者。涵盖用户池、身份池、令牌、CLI 操作和常见故障排查。
主要功能
- 01用户池注册与身份验证
- 02身份池联邦身份与临时凭证
- 03OAuth 2.0、OIDC 与令牌管理
- 04AWS CLI 常用命令参考
- 05安全建议与故障排查
适用场景
- 01为应用设置用户注册和登录
- 02为用户提供 MFA 与密码策略
- 03为用户获取访问 AWS 服务的凭证
- 04排查登录或令牌验证问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ itsmostafa/ aws-agent-skills --skill cognito安装后在 Claude Code 中输入/cognito确认已加载。
附带文件auth-flows.md
详细介绍
AWS Cognito
Amazon Cognito 为 Web 和移动应用提供身份验证、授权和用户管理。用户可以直接登录,也可以通过联合身份提供商登录。
目录
核心概念
用户池
用于注册和登录的用户目录。提供:
- 用户注册和身份验证
- OAuth 2.0 / OpenID Connect 令牌
- MFA 和密码策略
- 可自定义的 UI 和流程
身份池(联合身份)
提供临时 AWS 凭证,以便访问 AWS 服务。用户可以是:
- Cognito 用户池用户
- 社交身份(Google、Facebook、Apple)
- SAML/OIDC 企业身份
- 匿名访客
令牌
| 令牌 | 用途 | 有效期 |
|---|---|---|
| ID Token | 用户身份声明 | 1 小时 |
| Access Token | API 授权 | 1 小时 |
| Refresh Token | 获取新的 ID/Access Token | 30 天(可配置) |
常见模式
创建用户池
AWS CLI:
aws cognito-idp create-user-pool \
--pool-name my-app-users \
--policies '{
"PasswordPolicy": {
"MinimumLength": 12,
"RequireUppercase": true,
"RequireLowercase": true,
"RequireNumbers": true,
"RequireSymbols": true
}
}' \
--auto-verified-attributes email \
--username-attributes email \
--mfa-configuration OPTIONAL \
--user-attribute-update-settings '{
"AttributesRequireVerificationBeforeUpdate": ["email"]
}'
创建应用客户端
aws cognito-idp create-user-pool-client \
--user-pool-id us-east-1_abc123 \
--client-name my-web-app \
--generate-secret \
--explicit-auth-flows ALLOW_USER_SRP_AUTH ALLOW_REFRESH_TOKEN_AUTH \
--supported-identity-providers COGNITO \
--callback-urls https://myapp.com/callback \
--logout-urls https://myapp.com/logout \
--allowed-o-auth-flows code \
--allowed-o-auth-scopes openid email profile \
--allowed-o-auth-flows-user-pool-client \
--access-token-validity 60 \
--id-token-validity 60 \
--refresh-token-validity 30 \
--token-validity-units '{
"AccessToken": "minutes",
"IdToken": "minutes",
"RefreshToken": "days"
}'
注册用户
import boto3
import hmac
import hashlib
import base64
cognito = boto3.client('cognito-idp')
def get_secret_hash(username, client_id, client_secret):
message = username + client_id
dig = hmac.new(
client_secret.encode('utf-8'),
message.encode('utf-8'),
digestmod=hashlib.sha256
).digest()
return base64.b64encode(dig).decode()
response = cognito.sign_up(
ClientId='client-id',
SecretHash=get_secret_hash('[email protected]', 'client-id', 'client-secret'),
Username='[email protected]',
Password='SecurePassword123!',
UserAttributes=[
{'Name': 'email', 'Value': '[email protected]'},
{'Name': 'name', 'Value': 'John Doe'}
]
)
确认注册
cognito.confirm_sign_up(
ClientId='client-id',
SecretHash=get_secret_hash('[email protected]', 'client-id', 'client-secret'),
Username='[email protected]',
ConfirmationCode='123456'
)
验证用户身份
response = cognito.initiate_auth(
ClientId='client-id',
AuthFlow='USER_SRP_AUTH',
AuthParameters={
'USERNAME': '[email protected]',
'SECRET_HASH': get_secret_hash('[email protected]', 'client-id', 'client-secret'),
'SRP_A': srp_a # From SRP library
}
)
# For simple password auth (not recommended for production)
response = cognito.admin_initiate_auth(
UserPoolId='us-east-1_abc123',
ClientId='client-id',
AuthFlow='ADMIN_USER_PASSWORD_AUTH',
AuthParameters={
'USERNAME': '[email protected]',
'PASSWORD': 'password',
'SECRET_HASH': get_secret_hash('[email protected]', 'client-id', 'client-secret')
}
)
tokens = response['AuthenticationResult']
id_token = tokens['IdToken']
access_token = tokens['AccessToken']
refresh_token = tokens['RefreshToken']
刷新令牌
response = cognito.initiate_auth(
ClientId='client-id',
AuthFlow='REFRESH_TOKEN_AUTH',
AuthParameters={
'REFRESH_TOKEN': refresh_token,
'SECRET_HASH': get_secret_hash('[email protected]', 'client-id', 'client-secret')
}
)
创建身份池
aws cognito-identity create-identity-pool \
--identity-pool-name my-app-identities \
--allow-unauthenticated-identities \
--cognito-identity-providers \
ProviderName=cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123,\
ClientId=client-id,\
ServerSideTokenCheck=true
获取 AWS 凭证
import boto3
cognito_identity = boto3.client('cognito-identity')
# Get identity ID
response = cognito_identity.get_id(
IdentityPoolId='us-east-1:12345678-1234-1234-1234-123456789012',
Logins={
'cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123': id_token
}
)
identity_id = response['IdentityId']
# Get credentials
response = cognito_identity.get_credentials_for_identity(
IdentityId=identity_id,
Logins={
'cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123': id_token
}
)
credentials = response['Credentials']
# Use credentials['AccessKeyId'], credentials['SecretKey'], credentials['SessionToken']
CLI 参考
用户池
| 命令 | 说明 |
|---|---|
aws cognito-idp create-user-pool | 创建用户池 |
aws cognito-idp describe-user-pool | 获取用户池详情 |
aws cognito-idp update-user-pool | 更新用户池设置 |
aws cognito-idp delete-user-pool | 删除用户池 |
aws cognito-idp list-user-pools | 列出用户池 |
用户
| 命令 | 说明 |
|---|---|
aws cognito-idp admin-create-user | 创建用户(管理员) |
aws cognito-idp admin-delete-user | 删除用户 |
aws cognito-idp admin-get-user | 获取用户详情 |
aws cognito-idp list-users | 列出用户 |
aws cognito-idp admin-set-user-password | 设置密码 |
aws cognito-idp admin-disable-user | 禁用用户 |
身份验证
| 命令 | 说明 |
|---|---|
aws cognito-idp initiate-auth | 启动身份验证 |
aws cognito-idp respond-to-auth-challenge | 响应 MFA 挑战 |
aws cognito-idp admin-initiate-auth | 管理员身份验证 |
最佳实践
安全性
- 为所有用户启用 MFA(至少设为可选)
- 使用强密码策略
- 启用高级安全功能(自适应身份验证)
- 在允许登录前验证邮箱/电话号码
- 敏感应用使用较短的令牌有效期
- 切勿在前端代码中暴露客户端密钥
用户体验
- 使用托管 UI 快速实现
- 使用 CSS 自定义 UI
- 妥善处理错误
- 清楚说明密码要求
架构
- 使用身份池访问 AWS 资源
- 使用访问令牌访问 API Gateway
- 安全存储刷新令牌
- 在令牌过期前实现令牌刷新
故障排除
用户无法登录
原因:
- 用户尚未确认
- 密码错误
- 用户已禁用
- 账户已锁定(尝试次数过多)
调试:
aws cognito-idp admin-get-user \
--user-pool-id us-east-1_abc123 \
--username [email protected]
令牌验证失败
原因:
- 令牌已过期
- 用户池或客户端 ID 错误
- 令牌签名无效
验证 JWT:
import jwt
import requests
# Get JWKS
jwks_url = f'https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123/.well-known/jwks.json'
jwks = requests.get(jwks_url).json()
# Decode and verify (use python-jose or similar)
from jose import jwt
claims = jwt.decode(
token,
jwks,
algorithms=['RS256'],
audience='client-id',
issuer='https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc123'
)
托管 UI 无法使用
检查:
- 回调 URL 配置正确
- 已为用户池配置域名
- 已启用 OAuth 设置
# Check domain
aws cognito-idp describe-user-pool \
--user-pool-id us-east-1_abc123 \
--query 'UserPool.Domain'
速率限制
症状: TooManyRequestsException
解决方案:
- 实现指数退避
- 申请提高配额
- 适当缓存令牌
参考资料
评论
支持 Markdown