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

AWS Cognito用户池自定义认证流iOS实现的重复调用疑问

为什么AWS Cognito自定义认证流中会出现两次set(result: details)调用?

我来帮你梳理下这个问题——你遇到的两次调用set(result: details)的情况,其实是因为对Cognito自定义认证的iOS端流程逻辑理解有偏差,咱们一步步拆解:

问题根源:对getCustomChallengeDetails触发时机的错误处理

Cognito自定义认证在iOS端的AWSCognitoIdentityCustomAuthentication处理器中,getCustomChallengeDetails会被触发两次,但两次的作用完全不同:

  1. 第一次触发:此时challengeParameters为空,这是Cognito发起的初始挑战请求——它在询问客户端:「你是否准备好接收自定义挑战?」。这时候你不需要提交任何验证码,而是应该触发「发送验证码到用户邮箱」的逻辑,同时弹出验证码输入UI等待用户输入。
  2. 第二次触发:当后端触发器完成验证码发送后,Cognito会再次调用这个方法(此时challengeParameters会带上会话等必要参数),这一步通常不需要直接提交结果,真正的提交应该由用户输入验证码后手动触发。

而你的代码里,在challengeParameters.count > 0的第二次调用时,自动取了输入框的内容提交了一次;之后用户点击提交按钮时又手动调用了一次,所以出现了两次重复提交!

正确的处理流程

你需要把「自动提交」和「用户手动提交」的逻辑彻底分开:

1. 修正getCustomChallengeDetails的逻辑

只负责初始化、触发验证码发送和弹出输入UI,不自动提交结果:

func getCustomChallengeDetails(_ authenticationInput: AWSCognitoIdentityCustomAuthenticationInput, customAuthCompletionSource: AWSTaskCompletionSource<AWSCognitoIdentityCustomChallengeDetails>) {
    self.customAuthenticationCompletion = customAuthCompletionSource
    
    if authenticationInput.challengeParameters.isEmpty {
        // 第一次调用:触发后端发送验证码的逻辑
        self.sendVerificationCodeToUser()
        // 弹出验证码输入界面
        DispatchQueue.main.async {
            self.present(self.codeInputVC, animated: true)
        }
    } else {
        // 第二次调用:可以读取challengeParameters中的会话信息(如果触发器需要),但不要自动提交验证码
        // 比如 let session = authenticationInput.challengeParameters["SESSION"]
    }
}

2. 用户手动提交验证码时再调用set(result:)

只有当用户输入完成并主动点击提交按钮时,才执行提交操作:

@IBAction func submitCodeTapped(_ sender: UIButton) {
    guard let code = codeTextField.text, !code.isEmpty else {
        // 提示用户输入验证码
        return
    }
    let details = AWSCognitoIdentityCustomChallengeDetails(
        challengeResponses: ["CODE": code])
    details.initialChallengeName = "CUSTOM_CHALLENGE"
    self.customAuthenticationCompletion?.set(result: details)
    self.dismiss(animated: true)
}

补充说明:关于didCompleteStepWithError

你提到的这个方法确实容易误导人——它不管认证步骤成功还是失败都会被调用:

  • 当步骤成功时,error为nil,你可以在这里处理后续逻辑(比如跳转到主界面)
  • 当步骤失败时,error会包含具体错误信息(比如验证码错误),你可以在这里提示用户重新输入

这样修改后,就只会有一次有效的验证码提交调用,也就是用户手动触发的那次,彻底避免了重复提交的问题。

内容的提问来源于stack exchange,提问作者Carl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:33:14