尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

AWS SDK for Python(Boto3)操作 Amazon Cognito Identity Provider 实战:从用户注册、MFA 到身份池认证全流程指南

发布时间:2026/9/28 21:06:55

资讯中心
01
ARTICLE

AWS SDK for Python(Boto3)操作 Amazon Cognito Identity Provider 实战:从用户注册、MFA 到身份池认证全流程指南

AWS SDK for Python(Boto3)操作 Amazon Cognito Identity Provider 实战:从用户注册、MFA 到身份池认证全流程指南
示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载Amazon Cognito Identity Provider 为 Web 与移动应用提供用户认证与授权能力。本文以本仓库python/example_code/cognito目录下的示例代码为核心系统讲解如何用 AWS SDK for PythonBoto3实现用户注册、邮箱确认、多因素认证MFA设置与登录、受跟踪设备免 MFA 登录以及基于身份池Identity Pools的增强流/基础流联邦认证。读完本文你将能够直接复用仓库中的封装类与场景脚本搭建一套完整的 Cognito 认证流程。概览Cognito Identity Provider 与 Boto3Amazon Cognito Identity Provider 负责处理 Web 和移动应用的用户认证与授权。仓库中 cognito/README.md 是这一组示例的总入口它展示了如何使用 AWS SDK for PythonBoto3与该服务交互。示例代码的整体结构如下目录/文件作用hello/hello_cognito.py入门示例分页列出用户池ListUserPoolscognito_idp_actions.py核心封装类CognitoIdentityProviderWrapper涵盖 12 个单动作 APIscenario_signup_user_with_mfa.py场景脚本注册用户并配置 MFA、使用受跟踪设备登录scenarios/identity_pools_example_demo身份池联邦认证 Web 演示增强流与基础流test基于 botocore Stubber 的单元测试requirements.txt依赖清单运行成本与安全须知运行本示例代码可能产生 AWS 账户费用运行测试同样可能产生费用。官方建议遵循以下原则最低权限least privilege仅授予完成任务所需的最小权限不要使用管理权限运行示例。区域可用性示例代码并非在所有 AWS 区域都经过测试需参考 AWS Regional Services 列表确认所用区域是否支持 Cognito。环境准备与依赖安装前置条件运行这些示例的前置条件与python目录整体要求一致参见 python/README.md。核心要求包括已配置好 AWS 凭证可被 Boto3 发现的凭证链如~/.aws/credentials或环境变量。具备访问 Amazon Cognito 服务的 IAM 权限。Python 3 环境建议使用虚拟环境隔离依赖。安装依赖在虚拟环境中执行以下命令安装示例所需的包python -m pip install -r requirements.txtrequirements.txt 中声明了四类依赖各自的用途如下包版本约束用途boto31.26.79AWS SDK for Python提供cognito-idp客户端pytest7.2.1运行示例配套的单元测试qrcode7.4.2将 MFA 密钥生成二维码供认证 App 扫码绑定pycognito2022.12.0提供 SRPSecure Remote Password协议计算用于设备注册与受跟踪设备登录快速开始Hello CognitoListUserPools入门示例位于 hello/hello_cognito.py演示如何创建cognito-idp客户端并分页列出账户下的用户池import boto3 # Create a Cognito Identity Provider client cognitoidp boto3.client(cognito-idp) # Initialize a paginator for the list_user_pools operation paginator cognitoidp.get_paginator(list_user_pools) # Create a PageIterator from the paginator page_iterator paginator.paginate(MaxResults10) # Initialize variables for pagination user_pools [] # Handle pagination for page in page_iterator: user_pools.extend(page.get(UserPools, [])) # Print the list of user pools print(User Pools for the account:) if user_pools: for pool in user_pools: print(fName: {pool[Name]}, ID: {pool[Id]}) else: print(No user pools found.)值得注意的两个实现细节通过get_paginator(list_user_pools)创建分页器用MaxResults10控制每页大小再以 PageIterator 自动翻页合并结果。这是一种通用的 Boto3 分页模式可避免手动处理NextToken。示例对UserPools字段做了空值保护page.get(UserPools, [])确保账户下没有用户池时也能正常打印提示信息。运行方式python hello/hello_cognito.py单动作 APICognitoIdentityProviderWrapper 封装类详解核心实现集中在 cognito_idp_actions.py它定义了一个封装类CognitoIdentityProviderWrapper把用户生命周期中的 12 个 Cognito API 动作封装成可复用的方法。构造时只需传入cognito-idp客户端、用户池 ID 和客户端 IDclass CognitoIdentityProviderWrapper: Encapsulates Amazon Cognito actions def __init__(self, cognito_idp_client, user_pool_id, client_id, client_secretNone): :param cognito_idp_client: A Boto3 Amazon Cognito Identity Provider client. :param user_pool_id: The ID of an existing Amazon Cognito user pool. :param client_id: The ID of a client application registered with the user pool. :param client_secret: The client secret, if the client has a secret. self.cognito_idp_client cognito_idp_client self.user_pool_id user_pool_id self.client_id client_id self.client_secret client_secretclient_secret参数是可选的如果客户端应用配置了密钥所有认证类请求都需要附带SecretHash。SecretHash 计算原理_secret_hash方法实现了 Cognito 要求的 HMAC-SHA256 哈希cognito_idp_actions.pydef _secret_hash(self, user_name): key self.client_secret.encode() msg bytes(user_name self.client_id, utf-8) secret_hash base64.b64encode( hmac.new(key, msg, digestmodhashlib.sha256).digest() ).decode() logger.info(Made secret hash for %s: %s., user_name, secret_hash) return secret_hash其本质是以客户端密钥为 HMAC 密钥以用户名 客户端ID为消息做 SHA-256 摘要再经 Base64 编码。只要client_secret非空sign_up_user、resend_confirmation、confirm_user_sign_up、start_sign_in、respond_to_mfa_challenge都会自动附加该哈希这正是「客户端应用带密钥」场景的完整实现。用户注册与确认链路SignUpsign_up_usercognito_idp_actions.py#L57向 Cognito 发起注册携带用户名、密码和email用户属性并处理UsernameExistsException异常——当用户已存在时通过AdminGetUser查询其状态判断是否已完成确认def sign_up_user(self, user_name, password, user_email): try: kwargs { ClientId: self.client_id, Username: user_name, Password: password, UserAttributes: [{Name: email, Value: user_email}], } if self.client_secret is not None: kwargs[SecretHash] self._secret_hash(user_name) response self.cognito_idp_client.sign_up(**kwargs) confirmed response[UserConfirmed] except ClientError as err: if err.response[Error][Code] UsernameExistsException: response self.cognito_idp_client.admin_get_user( UserPoolIdself.user_pool_id, Usernameuser_name ) logger.warning( User %s exists and is %s., user_name, response[UserStatus] ) confirmed response[UserStatus] CONFIRMED else: logger.error( Couldnt sign up %s. Heres why: %s: %s, user_name, err.response[Error][Code], err.response[Error][Message], ) raise return confirmed这里展示了异常处理的最佳实践对可预期的业务异常用户已存在做分支处理对未知异常统一记录Error.Code与Error.Message后重新抛出。ResendConfirmationCoderesend_confirmationcognito_idp_actions.py#L105提示 Cognito 重新发送确认邮件返回CodeDeliveryDetails包含投递渠道DeliveryMedium与目标地址Destination供调用方提示用户查收。ConfirmSignUpconfirm_user_sign_upcognito_idp_actions.py#L132使用用户邮箱收到的确认码调用confirm_sign_up。Cognito 要求用户确认后才能登录该方法成功时返回True。ListUserslist_userscognito_idp_actions.py#L165以UserPoolId为参数调用list_users返回用户池中的用户列表。管理员登录与 MFA 挑战链路AdminInitiateAuthstart_sign_incognito_idp_actions.py#L188使用管理员凭证发起登录采用ADMIN_USER_PASSWORD_AUTH认证流适合运行在安全服务器端的代码。首次登录且用户池要求 MFA 时Cognito 会返回MFA_SETUP挑战此时方法判断MFAS_CAN_SETUP中是否包含SOFTWARE_TOKEN_MFATOTP若包含则自动调用associate_software_token获取 MFA 密钥并合并进响应response self.cognito_idp_client.admin_initiate_auth(**kwargs) challenge_name response.get(ChallengeName, None) if challenge_name MFA_SETUP: if ( SOFTWARE_TOKEN_MFA in response[ChallengeParameters][MFAS_CAN_SETUP] ): response.update(self.get_mfa_secret(response[Session])) else: raise RuntimeError( The user pool requires MFA setup, but the user pool is not configured for TOTP MFA. This example requires TOTP MFA. )注意其中的防御性检查若用户池未配置 TOTP MFA示例会直接抛出RuntimeError避免在错误配置下继续执行。AssociateSoftwareTokenget_mfa_secretcognito_idp_actions.py#L242接收前一步登录返回的Session调用associate_software_token获取可绑定 MFA 应用的密钥SecretCode。VerifySoftwareTokenverify_mfacognito_idp_actions.py#L266用户将密钥录入认证 App 后输入动态验证码调用verify_software_token完成绑定验证返回状态字段Status。AdminRespondToAuthChallengerespond_to_mfa_challengecognito_idp_actions.py#L293完成两因素登录的第二步——以SOFTWARE_TOKEN_MFA挑战名、会话与 App 生成的验证码调用admin_respond_to_auth_challenge。成功时返回AuthenticationResult内含访问令牌。该方法的异常处理还专门识别了ExpiredCodeException提示用户 MFA 验证码可能已过期或被使用过需要等待 App 生成新码。设备跟踪与免 MFA 登录链路ConfirmDeviceconfirm_mfa_devicecognito_idp_actions.py#L343注册受跟踪设备。其核心是为设备生成 SRP 密码验证器password verifier先基于设备组键 设备键与设备密码计算哈希再生成随机盐并计算大整数幂运算最后将PasswordVerifier与Salt以 Base64 编码后传给confirm_device。设备被 Cognito 跟踪后其键与密码可用于后续登录而无需重新输入 MFA 码。InitiateAuth / RespondToAuthChallengesign_in_with_tracked_devicecognito_idp_actions.py#L409受跟踪设备登录走标准客户端认证流需要依次响应两个 SRP 挑战以USER_PASSWORD_AUTH认证流和DEVICE_KEY调用initiate_auth期望返回DEVICE_SRP_AUTH挑战借助pycognito的AWSSRP类计算SRP_A等参数调用respond_to_auth_challenge响应DEVICE_SRP_AUTH拿到DEVICE_PASSWORD_VERIFIER挑战后处理挑战参数生成PASSWORD_CLAIM_SECRET_BLOCK与PASSWORD_CLAIM_SIGNATURE再次调用respond_to_auth_challenge最终获得AuthenticationResult。每一步都有防御性检查若返回的挑战名与预期不符立即抛出RuntimeError说明实际挑战名便于定位配置问题。单动作 API 汇总封装方法底层 Cognito API说明sign_up_userSignUp/AdminGetUser注册新用户用户已存在时查询其确认状态resend_confirmationResendConfirmationCode重新发送确认码邮件confirm_user_sign_upConfirmSignUp用确认码确认用户list_usersListUsers列出用户池中的用户start_sign_inAdminInitiateAuth/AssociateSoftwareToken管理员流发起登录自动处理MFA_SETUP挑战get_mfa_secretAssociateSoftwareToken获取 MFA 绑定密钥verify_mfaVerifySoftwareToken验证 MFA App 绑定respond_to_mfa_challengeAdminRespondToAuthChallenge用 MFA 验证码完成登录confirm_mfa_deviceConfirmDevice注册受跟踪设备sign_in_with_tracked_deviceInitiateAuth/RespondToAuthChallenge用受跟踪设备免 MFA 登录场景一用户注册 MFA 受跟踪设备登录这是 README 中标注的主场景入口脚本为 scenario_signup_user_with_mfa.py它完整演示了以下六步用用户名、密码和邮箱注册用户用邮件中的验证码确认用户将 MFA 应用与用户绑定用密码 MFA 验证码登录注册受跟踪设备用密码与受跟踪设备信息登录免去再次输入 MFA 码。前提资源该场景需要以下 AWS 资源一个已配置「允许自助注册」的 Amazon Cognito 用户池一个用于认证的客户端 ID。创建方式运行 resources/cdk/cognito_scenario_user_pool_with_mfa 目录下的 CloudFormation/CDK 脚本详见后文「基础设施部署」小节。脚本会输出用户池 ID 与客户端 ID供运行场景时传入。运行场景python cognito_idp_actions.py实际运行入口是main()函数它接收两个命令行参数python scenario_signup_user_with_mfa.py user_pool_id client_id交互流程拆解run_scenario以问答demo_tools.question方式驱动流程核心逻辑是一个基于挑战名的状态机循环scenario_signup_user_with_mfa.py#L89-L135注册与确认调用sign_up_user若返回未确认则提示用户查收邮箱验证码可手动输入确认码也可选择重新发送确认码resend_confirmation最后调用confirm_user_sign_up完成确认。列出用户调用list_users打印当前用户池中的用户验证注册结果。登录与 MFA 挑战start_sign_in返回MFA_SETUP挑战时用qrcode库生成otpauth://totp/{user_name}?secret{SecretCode}的二维码并保存为qr.png自动打开浏览器供用户用 Google Authenticator 等 App 扫码随后输入 App 中的验证码经verify_mfa完成绑定。之后重新发起登录进入SOFTWARE_TOKEN_MFA挑战循环输入验证码直到respond_to_mfa_challenge返回访问令牌。设备确认从登录响应的NewDeviceMetadata中取出DeviceGroupKey与DeviceKey用os.urandom(40)生成随机设备密码调用confirm_mfa_device完成设备注册。受跟踪设备登录调用sign_in_with_tracked_device用设备键、组键与设备密码完成 SRP 登录全程无需再输入 MFA 码。场景结束时脚本会提醒示例用完记得删除用户池。场景二Amazon Cognito 身份池联邦认证演示身份池场景位于 scenarios/identity_pools_example_demo是一个 Web 演示应用展示身份池的多身份提供商联邦认证流程其详细说明见 web/README.md。演示内容该演示聚焦以下能力增强流Enhanced flow推荐的认证方式将GetId与GetCredentialsForIdentity合并为更简洁的调用链用户认证 → 提供商 Token → GetCredentialsForIdentity → AWS 临时凭证。优点包括单次 API 调用、实现更简单、性能更好、自动完成角色选择。基础流Basic flow传统认证方式调用链为用户认证 → 提供商 Token → GetId → GetOpenIdToken → AssumeRoleWithWebIdentity → AWS 凭证。优点包括更细粒度的控制、支持自定义角色选择与令牌检查、兼容旧系统。访客未认证访问为匿名用户签发受限的 AWS 服务访问凭证无需登录。身份提供商集成社交提供商Facebook、Amazon、Google、企业提供商OIDC、SAML 2.0含 Okta 示例、Cognito 用户池Hosted UI 用户名密码认证、开发者自定义提供商。架构与运行前端端口 8001负责交互式 UI 与流程可视化后端 OAuth 服务器端口 8006负责令牌交换与安全处理AWS 侧由 Cognito 身份池、IAM 角色与 STS 提供凭证Frontend (8001) Backend (8006) AWS Services ├── Interactive UI ├── OAuth Server ├── Cognito Identity Pools ├── Flow Demonstrations ├── Token Exchange ├── IAM Roles ├── Educational Modals ├── Security Handling └── STS (Credentials) └── Real-time Results └── Provider Integration启动步骤安装后端依赖pip install -r requirements.txt基于.env.example复制出.env并填入区域、身份池 ID、社交提供商凭证等启动后端python backend/oauth_server.py监听 8006 端口启动前端静态服务器cd frontend python -m http.server 8001浏览器访问http://localhost:8001。配置项由 backend/config/cognito_config.py 统一管理从.env读取REGION、USER_POOL_ID、IDENTITY_POOL_ID、APP_CLIENT_ID、APP_CLIENT_SECRET、DOMAIN、ACCOUNT_ID、SAML_PROVIDER、OIDC_PROVIDER_URL、DEVELOPER_PROVIDER_NAME以及认证/未认证角色 ARN。关键设计点服务端令牌交换客户端密钥不暴露给浏览器OAuth 回调与 Token 交换均在 8006 端口后端完成临时凭证所有 AWS 凭证均带有效期CORS 保护正确配置跨域请求处理错误净化从错误消息中过滤敏感信息。从源码结构看后端路由按认证流拆分为 basic_flow.py 与 enhanced_flow.py身份池相关操作集中在 identity_pool_manager.py便于对照学习两种流各自的 API 调用差异。基础设施部署创建启用 MFA 的用户池场景一依赖的用户池资源可以通过 resources/cdk/cognito_scenario_user_pool_with_mfa 目录下的脚本一键创建详见其 README.md。该脚本创建如下资源一个 Amazon Cognito 用户池配置为允许自助注册、邮箱验证、强制 MFA、允许设备跟踪一个可认证的关联客户端应用。方式一AWS CDK 部署在resources/cdk/cognito_scenario_user_pool_with_mfa目录下执行需安装 Node.js 与 AWS CDK该示例基于 AWS CDK 2.29.1 构建与测试npm install cdk deploy部署完成后输出用户池 ID 与客户端 ID类似Outputs: doc-example-cognito-scenario-signup-user-with-mfa.ClientId 123456789eo6cet40krEXAMPLE doc-example-cognito-scenario-signup-user-with-mfa.UserPoolId us-west-2_CzEXAMPLE销毁资源执行cdk destroy。方式二AWS CLICloudFormation部署在相同目录下执行aws cloudformation create-stack --template-body file://setup.yaml --stack-name YOUR_STACK_NAME注意栈名在区域与账户内必须唯一最多 128 字符可含数字与连字符。栈创建通常不到一分钟可用aws cloudformation describe-stacks --stack-name YOUR_STACK_NAME查询状态StackStatus为CREATE_COMPLETE即就绪。获取输出值aws cloudformation describe-stacks --stack-name STACK_NAME --query Stacks[0].Outputs --output text结果类似UserPoolId us-west-2_oBEXAMPLE ClientId 123456789unqtb9jq4bEXAMPLE销毁资源执行aws cloudformation delete-stack --stack-name YOUR_STACK_NAME。测试基于 botocore Stubber 的单元测试示例附带测试位于 test 目录运行测试同样可能产生 AWS 账户费用。测试运行的整体说明参见 python/README.md。test_cognito_idp_actions.py 使用botocore.stub的 Stubber 机制离线打桩 AWS 响应并不真正访问 AWS覆盖了封装类的全部方法test_sign_up_user通过参数化组合client_secret与error_code四种情况覆盖正常注册、带密钥注册、未知异常与UsernameExistsException用户已存在时回退到admin_get_user查状态四条路径test_start_sign_in验证ADMIN_USER_PASSWORD_AUTH返回MFA_SETUP挑战后自动调用associate_software_token拿到SecretCodetest_sign_in_with_tracked_device用stub_runner依次打桩DEVICE_SRP_AUTH与DEVICE_PASSWORD_VERIFIER两个挑战验证 SRP 设备登录的完整调用链。从测试断言可以看到各方法的关键行为契约例如sign_up_user返回的confirmed与打桩值一致、respond_to_mfa_challenge返回AuthenticationResult[AccessToken]、confirm_mfa_device返回UserConfirmationNecessary等。test_scenario_signup_user_with_mfa.py则对场景脚本做进一步集成验证。进一步学习路径python/README.md 提供该语言目录下所有示例的通用前置条件与测试运行说明cognito_idp_actions.py 是理解用户池认证 API 调用的最佳起点每个方法都附有参数与返回值的详细 docstringscenario_signup_user_with_mfa.py 演示挑战-响应机制如何驱动 MFA 与设备跟踪的完整状态流转web/README.md 给出了身份池两种认证流的选择依据增强流适合新应用与移动端基础流适合需要自定义角色选择或令牌检查的场景SAML 提供商仅支持增强流以及 Google、Facebook、SAML、用户池各提供商的配置步骤与常见故障排查方法。仓库中的示例代码均遵循 Apache-2.0 协议可直接参考、运行与二次开发。建议在动手前先用 CloudFormation/CDK 脚本创建独立的用户池与客户端避免影响现有生产资源。赞分享示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载相关推荐AWS SDK for Java V2 操作 Amazon Cognito用户池、身份池与 MFA 场景实战指南AWS SDK for Java V2 操作 Amazon Cognito用户池、身份池与 MFA 场景实战指南 导读 本文基于 aws doc sdk ex示例工程教程后端使用 AWS SDK for JavaScript (v3) 实战 Amazon Cognito Identity Provider用户池认证、MFA 与 Lambda 触发器使用 AWS SDK for JavaScript v3 实战 Amazon Cognito Identity Provider用户池认证、MFA 与 Lam示例工程教程后端使用 AWS SDK for .NET (v4) 操作 Amazon Cognito Identity Provider用户注册、TOTP 多因素认证与用户池管理实战指南使用 AWS SDK for .NET v4 操作 Amazon Cognito Identity Provider用户注册、TOTP 多因素认证与用户池管理示例工程教程后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。