如何在AWS Cognito中配置邮箱或手机号二选一的注册选项?
AWS Cognito 实现注册时邮箱/手机号二选一必填配置方案
Cognito 原生没有提供字段互斥二选一的内置规则,需要通过控制台基础配置+触发器逻辑配合实现,步骤如下:
一、用户池基础配置
- 进入Cognito控制台,打开目标用户池的配置页,找到「登录标识」配置项:选择「用户名」作为核心登录标识,不要勾选「强制将邮箱/手机号作为必填登录别名」的选项
- 下滑到「标准属性」配置区:取消
email、phone_number两个属性的「必填」勾选,仅保留用户名、密码为平台级必填项 - 进入「验证机制」配置页:将邮箱、手机号的验证策略全部设置为「可选验证」,不要绑定注册时必须验证某一渠道的规则
二、注册流程双层校验
因为Cognito控制台没有自定义字段必填规则的入口,需要在业务侧和Cognito触发器层分别做校验兜底:
- 前端表单层做第一道拦截:注册页保留用户名、邮箱/手机号输入框、密码、确认密码四个核心模块,校验规则为:
- 密码和确认密码必须一致,否则直接提示不允许提交
- 邮箱、手机号两个字段不能同时为空,也不需要求用户同时填写,只要其中一个符合格式规则(邮箱符合通用邮箱正则、手机号符合E.164号码格式)即可放行提交
- 给用户池绑定预注册(Pre Sign-up)Lambda触发器做第二道兜底校验,避免非法请求绕过前端直接调用Cognito接口,参考代码如下:
exports.handler = async (event) => { const userAttributes = event.request.userAttributes; const validEmail = !!userAttributes.email && userAttributes.email.trim().length > 0; const validPhone = !!userAttributes.phone_number && userAttributes.phone_number.trim().length > 0; // 二选一规则校验:同时为空/同时填写都直接拦截 if (validEmail === validPhone) { throw new Error("注册时需且仅需提供邮箱、手机号其中一项"); } // 按用户提交的渠道自动触发对应验证流程 if (validEmail) { event.response.autoVerifyEmail = true; } if (validPhone) { event.response.autoVerifyPhone = true; } // 关闭自动确认,等用户完成对应渠道的验证码校验后再激活账号 event.response.autoConfirmUser = false; return event; };
三、后续适配说明
- 如果你需要支持用户后续用自己填写的邮箱/手机号登录,可以在预注册触发器里,把用户提交的邮箱/手机号写入对应用户的
preferred_username别名属性,不需要额外修改用户池配置 - 验证码发送逻辑会自动匹配用户提交的渠道,不会出现同时给邮箱和手机号发验证码的情况
避坑提示:绝对不要在Cognito标准属性配置里把email或phone_number设为必填,一旦勾选必填,Cognito会在接口接入层直接拦截缺少对应字段的请求,后续触发器逻辑完全不会触发,根本无法实现二选一的效果。
内容的提问来源于stack exchange,提问作者YulePale
相关产品推荐
相关产品推荐

