如何在Amazon Cognito中结合Hosted UI与自定义认证流适配OIDC协议
实现Amazon Cognito Hosted UI + OIDC + 自定义OTP认证流方案
要在Cognito Hosted UI的OIDC流程中替换用户名密码为邮箱/短信OTP,核心是通过自定义认证Lambda触发器改造Hosted UI的认证环节,同时保持OIDC流程的兼容性。以下是具体实现步骤:
1. 配置用户池自定义认证触发器
在Cognito用户池的「触发器」页面,启用并关联以下Lambda触发器(按需调整):
- Define Auth Challenge:控制认证流程的步骤逻辑,比如先要求用户提供身份(邮箱/手机号),再要求输入OTP。
- Create Auth Challenge:生成OTP并通过SES(邮箱)或SNS(短信)发送给用户。
- Verify Auth Challenge Response:校验用户输入的OTP是否有效。
- Pre Authentication(可选):预处理用户请求,比如检查用户状态、过滤非法请求。
2. 编写Lambda触发器核心逻辑
Define Auth Challenge 示例
exports.handler = async (event) => { // 首次请求:发起自定义挑战(要求用户输入身份) if (event.request.session.length === 0) { event.response.challengeName = 'CUSTOM_CHALLENGE'; event.response.failAuthentication = false; event.response.issueTokens = false; } // 上一步挑战验证通过:颁发令牌 else if (event.request.session.slice(-1)[0].challengeResult === true) { event.response.issueTokens = true; event.response.failAuthentication = false; } // 验证失败:终止认证 else { event.response.failAuthentication = true; } return event; };
Create Auth Challenge 示例(短信OTP)
const AWS = require('aws-sdk'); const sns = new AWS.SNS(); exports.handler = async (event) => { if (event.request.challengeName === 'CUSTOM_CHALLENGE') { // 生成6位OTP const otp = Math.floor(100000 + Math.random() * 900000).toString(); // 发送短信(需确保用户已绑定手机号属性) await sns.publish({ Message: `Your verification code: ${otp}`, PhoneNumber: event.request.userAttributes.phone_number }).promise(); // 保存OTP供后续验证使用 event.response.privateChallengeParameters = { otp }; // 向Hosted UI返回公开参数(比如显示用户手机号的后四位) event.response.publicChallengeParameters = { phone: event.request.userAttributes.phone_number.slice(-4) }; } return event; };
Verify Auth Challenge Response 示例
exports.handler = async (event) => { // 校验用户输入的OTP与Lambda保存的是否一致 event.response.answerCorrect = event.request.challengeAnswer === event.request.privateChallengeParameters.otp; return event; };
3. 配置Hosted UI与OIDC
- 在用户池的「应用客户端」中,确保启用所需的OIDC流程(授权码流/隐式流等),并配置正确的回调URL、注销URL。
- 无需修改Hosted UI的前端代码:Cognito会根据自定义认证流的逻辑,动态渲染对应的输入界面(先显示身份输入框,验证身份后显示OTP输入框)。
4. 关键注意事项
- 用户必须已在Cognito用户池中绑定邮箱或手机号属性,否则无法发送OTP。
- 给Lambda配置正确的权限:比如SES发送邮件权限、SNS发送短信权限、读取Cognito用户属性的权限。
- 测试流程:先通过Cognito用户池的「测试」功能验证自定义认证流是否正常,再对接Hosted UI的OIDC流程。
- 可扩展:在
Create Auth Challenge中加入OTP过期逻辑,或在Pre Authentication中增加风险校验。
内容的提问来源于stack exchange,提问作者pirent
相关产品推荐
相关产品推荐

