如何在Cognito创建认证Lambda触发器中识别用户登录所用别名?
可以在Create Auth Challenge触发器中识别用户使用的登录别名
当然可以识别用户登录时使用的是邮箱还是手机号别名,具体可以通过触发器事件中的参数结合简单逻辑判断实现,以下是两种可行方案:
方案1:直接对比触发器事件中的用户属性
当用户通过别名发起认证请求时,Cognito会在Create Auth Challenge触发器的事件对象中返回用户的完整属性集合,你可以直接将用户输入的别名(即event.request.username)与event.request.userAttributes中的email和phone_number属性值做对比:
def lambda_handler(event, context): # 获取用户输入的登录别名 login_alias = event["request"]["username"] # 获取用户的Cognito属性 user_attributes = event["request"]["userAttributes"] # 判断使用的别名类型 if login_alias == user_attributes.get("email"): alias_type = "email" elif login_alias == user_attributes.get("phone_number"): alias_type = "phone_number" else: alias_type = "unknown" # 这里可以根据别名类型执行不同逻辑,比如发送邮箱验证码/短信验证码 print(f"用户使用{alias_type}别名登录") return event
注意事项
- 确保用户输入的手机号格式与Cognito存储的
phone_number属性格式完全一致(比如是否带国家区号+xx),否则会匹配失败。如果前端允许用户输入不带区号的手机号,可以在Lambda中统一格式后再做对比。
方案2:调用AdminGetUser API验证(更可靠)
如果需要更严谨的验证(比如用户可能修改过别名属性),可以调用Cognito的AdminGetUser API获取用户最新的属性信息,再做对比:
import boto3 cognito_client = boto3.client("cognito-idp") def lambda_handler(event, context): user_pool_id = event["userPoolId"] login_alias = event["request"]["username"] # 调用API获取用户详细信息 response = cognito_client.admin_get_user( UserPoolId=user_pool_id, Username=login_alias ) # 转换属性为字典格式 user_attributes = {attr["Name"]: attr["Value"] for attr in response["UserAttributes"]} # 判断别名类型 if login_alias == user_attributes.get("email"): alias_type = "email" elif login_alias == user_attributes.get("phone_number"): alias_type = "phone_number" else: alias_type = "unknown" # 后续业务逻辑处理 return event
权限配置
使用该方案时,需要给Lambda函数添加cognito-idp:AdminGetUser的权限,你可以在SAM模板中为Lambda的IAM角色添加如下策略:
LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: CognitoAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: cognito-idp:AdminGetUser Resource: !Sub "arn:aws:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${UserPool}"
内容的提问来源于stack exchange,提问作者Rafael de Carvalho
相关产品推荐
相关产品推荐

