You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:42:50