如何配置Amazon Cognito支持单用户邮箱/手机号OTP无密码登录?
实现Amazon Cognito单用户邮箱/手机号任意OTP登录
可以实现单用户混用邮箱或手机号进行OTP无密码登录,核心是通过用户池别名配置配合自定义认证Lambda逻辑调整来实现,具体步骤如下:
1. 配置用户池别名(Alias)
- 进入Amazon Cognito用户池设置,找到登录选项
- 勾选允许用户使用以下方式登录中的邮箱地址和电话号码,将它们设为登录别名
- 确保用户名必填选项保持启用(或根据需求调整,但需保证用户有唯一基础用户名)
- 保存配置后,新创建的用户会自动支持用邮箱/手机号作为登录凭证;对于已有用户,需确保其邮箱和手机号属性已正确填充,且在用户池中唯一
2. 调整自定义认证Lambda触发器
重点修改DefineAuthChallenge和CreateAuthChallenge函数的逻辑,处理非主属性登录时的用户查找问题:
2.1 扩展DefineAuthChallenge函数逻辑
当收到userNotFound: true的事件时,不要直接判定用户不存在,而是根据输入的登录凭证(邮箱/手机号)主动查询用户:
const AWS = require('aws-sdk'); const cognito = new AWS.CognitoIdentityServiceProvider(); exports.handler = async (event) => { // 初始逻辑:如果用户已找到,按原有流程处理 if (!event.request.userNotFound) { // 你的原有挑战判定逻辑... return event; } // 用户未通过主属性找到,尝试按邮箱/手机号查找 const loginValue = event.request.userName; let user; // 判断输入是邮箱还是手机号,构造查询条件 const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(loginValue); const filter = isEmail ? `email = "${loginValue}"` : `phone_number = "${loginValue}"`; try { // 调用ListUsers接口查找用户 const listUsersResponse = await cognito.listUsers({ UserPoolId: event.userPoolId, Filter: filter, Limit: 1 }).promise(); if (listUsersResponse.Users.length > 0) { user = listUsersResponse.Users[0]; // 将找到的用户Username赋值给事件,让后续流程使用正确的用户标识 event.request.userName = user.Username; event.request.userNotFound = false; } } catch (err) { console.error('Error finding user:', err); } // 重新执行原有挑战判定逻辑(比如触发OTP发送) if (!event.request.userNotFound) { event.response.challengeName = 'CUSTOM_CHALLENGE'; event.response.failAuthentication = false; event.response.issueTokens = false; } else { event.response.failAuthentication = true; event.response.issueTokens = false; } return event; };
2.2 调整CreateAuthChallenge函数
确保函数能根据用户的邮箱或手机号属性发送OTP:
- 获取用户的邮箱/手机号属性(从
event.request.userAttributes中) - 根据用户输入的登录凭证类型,选择对应的属性发送OTP(比如如果用户用手机号登录,就发送到
phone_number;用邮箱登录则发送到email)
3. 配置Lambda权限
给自定义认证Lambda函数添加以下IAM权限,允许其查询Cognito用户:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cognito-idp:ListUsers", "cognito-idp:AdminGetUser" ], "Resource": "arn:aws:cognito-idp:你的区域:你的账号ID:userpool/你的用户池ID" } ] }
关键注意事项
- 确保用户的邮箱和手机号属性在用户池中唯一,避免多个用户共享同一邮箱/手机号导致登录冲突
- 处理Lambda函数的异常情况,比如查询用户失败时的错误捕获
- 测试时需覆盖两种登录场景:用主属性登录、用非主属性登录,验证OTP发送和验证流程均正常
参考资料
- Amazon Cognito用户池别名配置:官方文档中"Configuring sign-in options"章节
- 自定义认证Lambda触发器:官方文档中"Custom authentication flow Lambda triggers"章节
内容的提问来源于stack exchange,提问作者Juan Aguilar Guisado
相关产品推荐
相关产品推荐

