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

Swift中AWS身份池未认证访问不支持及DynamoDB认证问题

解决Cognito自定义登录后访问DynamoDB的未授权问题

嘿,我来帮你搞定这个认证问题!你遇到的NotAuthorizedException和identityId为nil的情况,核心原因是登录Cognito用户池后,没有把用户的认证凭证关联到Cognito身份池——这就导致DynamoDB操作时,身份池误以为你是未认证用户,但你的身份池又禁用了未认证访问。下面是具体的修复步骤:

1. 登录成功后关联用户池凭证到身份池

你原来的登录代码只完成了用户池的登录,但没有把这个登录状态同步到身份池。修改登录成功的回调部分,添加身份池的凭证关联逻辑:

}else{
    ActivityIndicator.stop()
    DispatchQueue.main.async {
        // 获取用户池返回的会话凭证
        guard let userSession = task.result else { 
            print("无法获取用户会话")
            return 
        }
        
        // 替换成你的区域和身份池ID
        let region = AWSRegionType.usEast1 // 比如你的区域是us-east-1
        let identityPoolId = "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        
        // 创建凭证提供者,关联用户池和身份池
        let credentialsProvider = AWSCognitoCredentialsProvider(
            regionType: region,
            identityPoolId: identityPoolId,
            identityProviderManager: AWSCognitoUserPoolsAuthProviderManager(pool: self.configuration.pool!)
        )
        
        // 设置默认AWS服务配置,让后续的DynamoDB操作使用这个认证后的配置
        let serviceConfig = AWSServiceConfiguration(region: region, credentialsProvider: credentialsProvider)
        AWSServiceManager.default().defaultServiceConfiguration = serviceConfig
        
        // 获取身份ID,确保后续操作能拿到合法的身份标识
        credentialsProvider.getIdentityId().continueWith(block: { identityTask in
            if let error = identityTask.error {
                print("获取Identity ID失败: \(error.localizedDescription)")
                return nil
            }
            
            if let identityId = identityTask.result {
                print("已获取认证身份ID: \(identityId)")
                // 现在再跳转到编辑页面,此时身份已认证
                let vc = self.storyboard?.instantiateViewController(withIdentifier: "EditProfileVC_sid") as! EditProfileVC
                self.navigationController?.pushViewController(vc, animated: true)
            }
            return nil
        })
    }
}

2. 修正DynamoDB保存逻辑,确保使用认证身份

原来的代码里stype?.append("soltype1")会直接崩溃(因为stype初始化为nil),同时要确保拿到已认证的identityId再赋值。修改保存代码:

@IBAction func save_profile(_ sender: UIButton) {
    // 先确认我们的凭证提供者是有效的
    guard let credentialsProvider = AWSServiceManager.default().defaultServiceConfiguration?.credentialsProvider as? AWSCognitoCredentialsProvider else {
        print("未找到合法的认证凭证提供者")
        return
    }
    
    // 获取已认证的Identity ID
    credentialsProvider.getIdentityId().continueWith(block: { task in
        guard let identityId = task.result else {
            print("获取Identity ID失败: \(task.error?.localizedDescription ?? "未知错误")")
            return nil
        }
        
        let dynamoDbMapper = AWSDynamoDBObjectMapper.default()
        let userItem = User()
        
        // 修正数组初始化,避免崩溃
        let stype: [String] = ["soltype1"]
        userItem._userId = identityId
        // userItem._soultypes = stype // 如果你需要这个字段的话
        userItem._about = "About Me"
        userItem._bday = "19-19-1991"
        userItem._culture = "Jain"
        userItem._email = "abc@gmail.com"
        userItem._mobile = 1234567890
        userItem._mobilePrefix = "+32"
        userItem._soulid = "mysid"
        
        // 保存数据到DynamoDB
        dynamoDbMapper.save(userItem, completionHandler: { error in
            if let error = error {
                print("DynamoDB保存失败: \(error.localizedDescription)")
                return
            }
            print("数据已成功保存到DynamoDB!")
        })
        return nil
    })
}

3. 检查身份池和IAM策略配置

最后还要确保你的后台配置没问题:

  • 确认Cognito身份池已经关联了你的用户池作为身份提供者(在AWS控制台的身份池设置里可以找到)。
  • 检查DynamoDB的IAM策略,允许认证用户(比如通过cognito-identity.amazonaws.com:sub标识的用户)执行PutItem、GetItem等操作。
  • 确认身份池的未认证访问是禁用的(这是你当前的配置,没问题,但要保证认证路径是畅通的)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 03:28:24