如何禁用Cognito自动确认用户场景下的邮件验证码发送
解决方案
问题根因
你当前先调用普通userPool.signUp接口的逻辑存在时序问题:Cognito在接收signUp请求后会第一时间触发验证邮件发送逻辑,你后续调用adminConfirmSignUp、修改email_verified属性的操作都在邮件发送触发之后,无法拦截邮件发送。
实现方案
有两种可落地的实现方式,你可以根据自己的业务场景选择:
方案1:针对自动确认用户改用AdminCreateUser接口(推荐)
该方案无需额外配置Cognito触发器,直接修改后端注册逻辑即可:
- 先判断待注册用户的角色:
- 如果是需要手动验证的用户,保留原有
signUp逻辑,正常触发邮件发送 - 如果是需要自动确认的用户,直接调用AWS Cognito的
AdminCreateUser接口,配置MessageAction: "SUPPRESS"参数即可禁止发送任何通知邮件,后续直接完成用户确认、属性修改操作即可。
- 如果是需要手动验证的用户,保留原有
对应的代码示例:
// 先判断用户角色走分支逻辑 if (用户属于自动确认角色) { const createUserParams = { UserPoolId: process.env.USER_POOL_ID!, Username: userData.email, UserAttributes: [ { Name: 'email', Value: userData.email }, { Name: 'email_verified', Value: 'true' } // 其他自定义属性在此补充 ], // 关键参数:禁止发送任何通知邮件 MessageAction: 'SUPPRESS' } // 创建用户 const createRes = await cognitoIdentityServiceProvider.adminCreateUser(createUserParams).promise() // 设置用户永久密码 await cognitoIdentityServiceProvider.adminSetUserPassword({ UserPoolId: process.env.USER_POOL_ID!, Username: userData.email, Password: userData.password, Permanent: true }).promise() success({ user: createRes.User.Username, sub: createRes.User.Attributes.find(i => i.Name === 'sub').Value }) } else { // 手动确认用户走原有signUp逻辑 userPool.signUp( userData.email, userData.password, attributeList, [], async (err, result) => { if (err) { failure(new HttpException(500, err.message)) } success({ user: result.user, sub: result.userSub }) } ) }
方案2:配置Cognito预注册Lambda触发器
如果你不想修改原有注册接口,可以新增Cognito的预注册(Pre Sign-up)触发器:
- 编写Lambda函数,在函数内判断注册用户的角色:
- 如果是自动确认角色,在回调的response参数里设置
autoConfirmUser: true、autoVerifyEmail: true - 如果是手动确认角色,不修改response参数直接返回即可
- 如果是自动确认角色,在回调的response参数里设置
- 将该Lambda绑定到你的Cognito用户池的预注册触发器上
Cognito会在注册流程的最开始执行该触发器,自动完成指定用户的确认和邮箱验证,不会再触发验证邮件发送。
注意事项
AdminCreateUser接口属于管理员接口,必须在后端服务调用,禁止暴露对应的AWS凭证到前端- 使用预注册触发器的场景需要给Lambda配置Cognito用户池的相关操作权限,避免执行报错
内容的提问来源于stack exchange,提问作者HexaCrop
相关产品推荐
相关产品推荐

