aws appsync - getting 401s from ios client

2019-08-25 06:28发布

问题:

So when i run queries from the aws console, things work great. However on my iOS client, i only get 401 errors.

I'm using the basic code from the tutorial and cognito auth:

    credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegion, identityPoolId: CognitoIdentityPoolId)

    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)")
    }

I've tried hooking up the cognito sign in ui, which does seem to sign me in, but I still get 401 errors from the appsync client.

NOTE: using apikeybased auth also works fine - but cognito is needed for this project.

Any help would be appreciated, I'm banging my head on this one.

回答1:

Do you have an inline policy on the IAM role for that Cognito Identity Pool that allows calls to your AWS AppSync API? It should look something like this:

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "appsync:GraphQL"
         ],
         "Resource": [
            "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/*"
         ]
      }
   ]
}

You'll need to set this on the Authenticated and/or UnAuthenticated Cognito Role depending on how you setup your pool. More details of the IAM policies can be found here: AppSync Security Guide - AWS_IAM Authorization

Additional answer

It might be a good idea to level set some things for your setup. First go to the AWS AppSync console and for your API click the Settings tab on the left and select AWS Identity and Access Management (IAM) as the Authorization Type. Click Save. Then on your desktop install the awsmobile CLI:

npm install -g awsmobile-cli

Next go into your local application project directory, initialize it and add in Cognito via the user-signin feature:

cd ./my-project
awsmobile init                #select defaults
awsmobile user-signin enable

This will create & configure a new Cognito User Pool and Cognito Identity Pool automatically for you with AWS Mobile Hub. It will also setup correct IAM policies however at this time it doesn't configure AppSync policy and you will need to do that manually.

Open the IAM console and click Roles on the left hand side. In the search box type in the name of the project you created with the awsmobile CLI above. One of the roles will have a prefix of _auth_MOBILEHUB and one will have _unauth_MOBILEHUB. Depending on if you're logging in or just using Cognito in an unauthenticated state, the client will assume one of these roles at runtime. Select that role (or do this for both) and click Add inline policy and then the JSON tab. Enter in the below policy (JUST FOR TESTING):

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "appsync:GraphQL"
         ],
         "Resource": [
            "*"
         ]
      }
   ]
}

Now if you're still getting 401 errors there is something else afoot in your service setup other than the client and you might want to open a ticket with AWS support. If however this is working now then you should make restrictions to this IAM policy so that it's not so permissive. I also recommend using a more restrictive policy for authenticated users.