如何捕获AWS Cognito中管理员创建用户完成NEW_PASSWORD_REQUIRED挑战事件?
针对你遇到的问题——捕获用户完成NEW_PASSWORD_REQUIRED挑战的事件并自动更新DynamoDB中的pending属性,有两种无需客户端上报的可行方案:
方案1:利用PostAuthentication Lambda触发器
当用户完成NEW_PASSWORD_REQUIRED挑战并成功登录后,Cognito会触发PostAuthentication触发器,这是最直接的处理方式。需要添加自定义用户属性来避免重复执行更新逻辑:
添加自定义用户属性
在Cognito用户池的属性设置中添加custom:isPending自定义属性(类型为字符串)。调用AdminCreateUser创建用户时,通过UserAttributes参数设置该属性为"Value": "true"。编写PostAuthentication Lambda函数
函数核心逻辑:import boto3 dynamodb = boto3.resource('dynamodb') cognito_idp = boto3.client('cognito-idp') user_table = dynamodb.Table('你的用户表名') user_pool_id = '你的用户池ID' def lambda_handler(event, context): # 获取用户信息 user_sub = event['request']['userAttributes']['sub'] is_pending = event['request']['userAttributes'].get('custom:isPending', 'false') if is_pending == 'true': # 更新DynamoDB的pending属性 user_table.update_item( Key={'sub': user_sub}, UpdateExpression='SET pending = :val', ExpressionAttributeValues={':val': False} ) # 更新Cognito用户属性,避免后续登录重复执行 cognito_idp.admin_update_user_attributes( UserPoolId=user_pool_id, Username=event['userName'], UserAttributes=[ {'Name': 'custom:isPending', 'Value': 'false'} ] ) return event配置触发器
将该Lambda函数关联到用户池的PostAuthentication触发器即可。
方案2:通过CloudTrail+EventBridge监听认证事件
如果不想修改用户池触发器,可以通过CloudTrail记录Cognito的认证事件,再用EventBridge过滤并触发处理逻辑:
开启CloudTrail记录
确保你的AWS账号已开启CloudTrail,并配置记录cognito-idp.amazonaws.com的API调用。创建EventBridge规则
配置事件模式,匹配RespondToAuthChallenge成功完成NEW_PASSWORD_REQUIRED挑战的事件:{ "source": ["aws.cognito-idp"], "detail-type": ["AWS API Call via CloudTrail"], "detail": { "eventSource": ["cognito-idp.amazonaws.com"], "eventName": ["RespondToAuthChallenge"], "requestParameters": { "challengeName": ["NEW_PASSWORD_REQUIRED"] }, "responseElements": { "challengeResult": ["Success"] } } }编写处理Lambda函数
从事件中提取用户名,找到对应DynamoDB条目并更新pending属性:import boto3 dynamodb = boto3.resource('dynamodb') user_table = dynamodb.Table('你的用户表名') def lambda_handler(event, context): username = event['detail']['requestParameters']['userName'] # 假设你的DynamoDB表用username作为主键,若用sub则需要先通过Cognito查询sub user_table.update_item( Key={'username': username}, UpdateExpression='SET pending = :val', ExpressionAttributeValues={':val': False} ) return {'statusCode': 200}关联规则与Lambda
将EventBridge规则的目标设置为上述Lambda函数,确保Lambda拥有DynamoDB更新权限。
内容的提问来源于stack exchange,提问作者Benjamin Sommer

