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

使用Amazon Cognito iOS首次API调用返回403问题求助

解决Amazon Cognito认证后API调用立即返回403的问题

从你给出的错误信息来看,问题非常明确:刚完成Cognito认证后发起的API调用,使用的是未授权(unauth)角色的凭证,而非认证后的授权(auth)角色凭证——这也是重启App后调用正常的原因:重启时AWSMobileClient会自动加载缓存的登录状态,刷新并获取到正确的授权角色凭证。

问题根源

你在user.getSession()的成功回调里立刻发起API调用,但此时AWSMobileClient还没来得及完成凭证的刷新和角色切换,依然在使用之前的未授权角色凭证,导致API网关拒绝请求。

解决方案

你需要确保在凭证完全切换到授权角色之后再发起API调用,这里有两种可靠的实现方式:

方式1:登录成功后手动刷新凭证

在getSession成功后,调用凭证提供者的refresh()方法,等待刷新完成再执行API调用:

let user = pool.currentUser() ?? pool.getUser()
user.getSession("myUsername", password: "myPassword", validationData: nil).continueOnSuccessWith { sessiontask -> Any? in
    // 手动刷新凭证,确保切换到授权角色
    self.credentialsProvider.refresh().continueWith { refreshTask in
        guard refreshTask.error == nil else {
            // 处理凭证刷新错误
            return nil
        }
        
        // 现在凭证已更新,可以安全发起API调用
        let request = AWSAPIGatewayRequest(httpMethod: "POST", urlString: "/my-api-endpoint", queryParameters: nil, headerParameters: nil, httpBody: nil)
        let serviceClient = AWSAPI_MY_AUTOGENERATED_Client.default()
        return serviceClient.invoke(request).continueOnSuccessWith(block: { (task) -> Any? in
            if let result = task.result, result.statusCode == 200 {
                // A: 一切正常 - 继续执行
            } else {
                // B: 处理错误(如403等)
            }
            return nil
        })
    }
    return nil
}

方式2:使用AWSMobileClient的状态监听(更推荐)

直接使用AWSMobileClient的登录方法,并监听其状态变化,当状态变为signedIn时,说明凭证已准备就绪:

首先,修改你的认证代码:

// 在视图控制器的合适位置(比如viewDidLoad)添加状态监听
AWSMobileClient.sharedInstance().addStateChangeObserver(self) { [weak self] state, error in
    guard let self = self else { return }
    switch state {
    case .signedIn:
        // 用户已登录且凭证已切换到授权角色,发起API调用
        self.makeAuthorizedAPICall()
    default:
        break
    }
}

// 发起登录请求
AWSMobileClient.sharedInstance().signIn(username: "myUsername", password: "myPassword") { result, error in
    guard error == nil else {
        // 处理登录失败
        print("登录错误:\(error!.localizedDescription)")
        return
    }
    // 登录成功后,等待状态监听触发signedIn事件
}

// 封装API调用方法
private func makeAuthorizedAPICall() {
    let request = AWSAPIGatewayRequest(httpMethod: "POST", urlString: "/my-api-endpoint", queryParameters: nil, headerParameters: nil, httpBody: nil)
    let serviceClient = AWSAPI_MY_AUTOGENERATED_Client.default()
    serviceClient.invoke(request).continueOnSuccessWith(block: { (task) -> Any? in
        if let result = task.result, result.statusCode == 200 {
            // A: 一切正常 - 继续执行
        } else {
            // B: 处理错误(如403等)
        }
        return nil
    })
}

额外注意事项

  • 你的AppDelegate配置是正确的,AWSMobileClient.sharedInstance().interceptApplication已经帮你处理了基础的初始化逻辑,不需要改动。
  • 尽量避免直接操作AWSCognitoIdentityUserPool的getSession,而是使用AWSMobileClient的登录方法,它会更可靠地管理凭证生命周期和角色切换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:24:56