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
相关产品推荐
相关产品推荐

