所以我设置了cognito和appsync,并将它们连接到我的iOS客户端。 Appsync在控制台上运行良好,但是当我从iOS发出任何请求时,我收到401错误而没有任何错误消息。我可以登录和退出cognito罚款。我想我可能会把错误的东西传给某些东西?
这是我的应用委托代码: 导入UIKit 导入AWSAppSync 导入AWSS3 导入AWSCognitoIdentityProvider
var credentialsProvider: AWSCognitoCredentialsProvider?
var pool: AWSCognitoIdentityUserPool?
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var storyboard: UIStoryboard? {
return UIStoryboard(name: "Main", bundle: nil)
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
AWSDDLog.sharedInstance.logLevel = .verbose
AWSDDLog.add(AWSDDTTYLogger.sharedInstance)
let configuration = AWSServiceConfiguration(region: AWSRegion, credentialsProvider: nil)
let poolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: CognitoAppId, clientSecret: nil, poolId: CognitoPoolId)
AWSCognitoIdentityUserPool.register(with: configuration, userPoolConfiguration: poolConfiguration, forKey: CognitoIdentityPoolId)
pool = AWSCognitoIdentityUserPool(forKey: CognitoIdentityPoolId)
NSLog("cognito pool username: \(pool?.currentUser()?.username ?? "unknown")")
pool!.delegate = self
credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegion, identityPoolId: CognitoIdentityPoolId, identityProviderManager: pool!)
let databaseURL = URL(fileURLWithPath:NSTemporaryDirectory()).appendingPathComponent(database_name)
do {
// Initialize the AWS AppSync configuration
let appSyncConfig = try AWSAppSyncClientConfiguration(url: AppSyncEndpointURL, serviceRegion: AWSRegion,
credentialsProvider: credentialsProvider!,
databaseURL:databaseURL)
// Initialize the AppSync client
appSyncClient = try AWSAppSyncClient(appSyncConfig: appSyncConfig)
// Set id as the cache key for objects
appSyncClient?.apolloClient?.cacheKeyForObject = { $0["id"] }
}
catch {
NSLog("Error initializing appsync client. \(error)")
}
return true
}
}
extension AppDelegate: AWSCognitoIdentityInteractiveAuthenticationDelegate {
func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
let tabController = self.window?.rootViewController as! UITabBarController
let loginViewController = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
DispatchQueue.main.async {
tabController.present(loginViewController, animated: true, completion: nil)
}
return loginViewController
}
}
并且说明了我得到的错误:
Error body: {
"errors" : [ {
"message" : "Unable to parse JWT token."
} ]
})
errorDescription: (401 unauthorized) Did not receive a successful HTTP code.
iam政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "appsync:GraphQL",
"Resource": "*"
}
]
}
IAM TRust关系:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-west-2:94OBSCURED"
}
}
}
]
}
如果您需要更多详细信息,请与我们联系。
答案 0 :(得分:2)
AppSync初始化很棘手。所有AWS文档/示例都提供了IAM或API密钥作为身份验证的示例。如果您在AppSync中将Cognito User Pools设置为Authentication,那么有两件事需要考虑。
1)创建类的扩展名,如下所示。
extension YourClassName: AWSCognitoUserPoolsAuthProvider {
func getLatestAuthToken() -> String {
let pool = AWSCognitoIdentityUserPool(forKey: APP_TITLE)
let session = pool.currentUser()?.getSession()
return (session?.result?.idToken?.tokenString)!
}
}
2)初始化AppSync时不要使用credentialsProvider。而是使用 userPoolsAuthProvider 。 userPoolsAuthProvider的值是在步骤1中创建的类。如果是相同的类,则可以是 self ,如果是单独的类,则可以是类名。
let appSyncConfig = try AWSAppSyncClientConfiguration.init(url: AppSyncEndpointURL, serviceRegion: AppSyncRegion, userPoolsAuthProvider:self, databaseURL:databaseURL)
CognitoUserPools需要JWT令牌,而IAM需要IdentityPoolProvider。传递credentialsProvider意味着告诉AppSync将IAM用作身份验证。
答案 1 :(得分:0)
好的问题是:如果您正在使用上述代码,则需要将appsync设置为通过IAM(不是Cognito)进行身份验证。这也需要更改您的解析器,因为传递给身份对象的参数对于IAM和Cognito是不同的。
这很令人困惑,因为您正在使用Cognito(用户池和联合身份用户池),但不要选择Cognito。
答案 2 :(得分:0)
在本文中,向下滚动并查看标题为“身份验证模式”的部分。这为使用AppSync时可用于iOS项目的api授权的选项提供了很好的参考。我发现这很有帮助。
https://awslabs.github.io/aws-mobile-appsync-sdk-ios/#configuration