aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.43k stars 2.12k forks source link

"No current user" Error When Accessing AppSync Query using API.graphql #1252

Closed reggie3 closed 5 years ago

reggie3 commented 6 years ago

Do you want to request a feature or report a bug? bug

What is the current behavior? Attempting to access an AppSync query that has no access control on it results in a "No current user" error.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than AWS Amplify. Create an AppSync API with "Amazon Cognito User Pool" as the Authorization type and "ALLOW" as the Default action. Connect it to a user pool. Create a query with that does not have @aws_auth directive as described in the AppSync security documentation here The query I created looks like this: image

What is the expected behavior? The query should be run without requiring a user to sign in

Which versions of Amplify, and which browser / OS are affected by this issue? Did this work in previous versions? Chrome Version 67.0.3396.99 Firefox 61.0 AWS-Amplify 1.0 AWS-Amplify-React 1.0

You can turn on the debug mode to provide more info for us by setting window.LOG_LEVEL = 'DEBUG'; in your app. Debug info indicates that the program is attempting to get the user from the user pool even though the user has not attempted to sign in yet: image

elorzafe commented 6 years ago

Hi @reggie3 thanks for your feedback. When you specify Amazon Cognito User Pool as the authorization type on your AppSync API, when you try to call the API it always need a jwt to authenticate. When you don't have directives on your query like you mention, it means that any user of the User Pool has access to the query, it doesn't mean that the API is open to everyone.

For the use case you have I can suggest you to create an Amazon Cognito Identity Pool. Identity pools can have configured an unauth an auth roles like the case you mention unauth role (No signed in user).

To configure IAM permissions you can take a look here.

Please let me know how it goes

reggie3 commented 6 years ago

Can I recommend that there be some way to call specific queries without requiring a token then? User Pool groups seem like a perfect way to authenticate. They are simple to reason about, analogous to non AWS techniques for grouping users, and powerful. Additionally, I think group permissions will become the "happy path" once you guys integrate Facebook, Google, and other logins into user pools without requiring using the Hosted UI.

I couldn't get the IAM method to work even when I gave the unauthenticated role full permissions as specified by this example taken from the documentation you linked:

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

I don't think learning IAM should be a requirement for what I'm trying to do so for now I'll go with the API_KEY method, and see where you guys take the library in the future.

j2d2 commented 6 years ago

Had a similar issue - this is not clear in the docs. ...changing to IAM with policies for the Auth & UnAuth Roles according to the IAM permissions link above made it so i could control the AppSync endpoints granularly.

But, I would like to manage some field level permissions with Cognito Groups - appears I can't pull this off with IAM as opposed to Cognito.

reggie3 commented 6 years ago

@j2d2 Have you figured out a way to have additional IAM roles? Power users or admins for example?

j2d2 commented 6 years ago

haven't solved this yet... Reading the Authorization Use Cases says that

the check uses $context.identity.username which will be the friendly user sign-up name if Amazon Cognito user pools is used and will be the user identity if AWS IAM is used (including Amazon Cognito Federated Identities). There are other values to store for an owner such as the unique "Amazon Cognito identity" value, which is useful when federating logins from multiple locations...

it then refers to the Resolver Mapping Template Context Reference, which explains the shape of the identity context, but the closest to an answer i see is in the "username" field description:

In case of AMAZON_COGNITO_USER_POOLS authorization, the value of username is the value of attribute cognito:username. In case of AWS_IAM authorization, the value of the username is the value of the AWS User Principal. We recommend that you use cognitoIdentityId if you are using AWS IAM authorization with credentials vended from Amazon Cognito federated identities.

So, if we have the cognitoIdentityId can we somehow query Cognito for a list of Groups for that User in the backend?

If not, the only "solution" i've come up with is to pass the groups in a custom header... but i expect this raises some security concerns... open to ideas!!

reggie3 commented 6 years ago

Right now, I'm leaning towards creating a separate table in DynamoDB to track user specific information using the user pool users' "sub" attribute or Cognito IAM ID as an ID for each user in that table, and keeping track of each user's groups there.

Unfortunately, that would still mean that I couldn't take advantage of the group directive in the AppSync schema. I'd work around that by using Lambdas to do the authorization and resolving on the queries that I'd want to restrict.

rayhaanq commented 6 years ago

Is there any solution/work around for this yet? I'm currently facing the same problem. For a type, I want reads to be allowed for the public, but writes only for a specific group of authenticated users

etwillbefine commented 6 years ago

I have the same issue. Identity Pool is configured to accept unauthenticated identities. Amplify is configured with Auth: { mandatorySignIn: false } identityPool and oauth settings for the hosted UI. AppSync and Amplify use AMAZON_COGNITO_USER_POOLS auth. Unauthenticated role from my Identity Pool is allowed to invoke and request graphql/AppSync.

The request I want to be publicly available will not be made. Instead the error "No current user" is thrown. When I change auth type to AWS_IAM everything works fine without further changes. I think its not intended to only allow authenticated users when using cognito user pool auth?!

aldarund commented 5 years ago

So basically when using AMAZON_COGNITO_USER_POOLS there cant be any public api? Really? Make zero sense. Having a way to create public api while still using cognito for auth users should be basic core functionality, i dont understand how its not here.

selipso commented 5 years ago

Any solutions or workarounds to this? I'm getting the same error keeping track of user identities. Tried sending a Bearer Token manually with an Interceptor as well, but didn't work. Going to try removing all @auth statements from my GraphQL schema next.

Edit: I think my problem is that I'm expecting DynamoDB access without having a logged-in user, which Amplify doesn't seem to support at this point. So, I'll have to store data locally in the meantime, and then create a syncing service layer to create rows in my DynamoDB table once the user has registered.

GroveDev commented 5 years ago

I'm on this boat too. Not able to do queries while not logged in makes no sense to me either. I'm looking forward to any fix on this one.

undefobj commented 5 years ago

@reggie3 @GroveDev @selipso @aldarund @etwillbefine @rayhaanq to clarify, it sounds like you want to allow public access to your AppSync GraphQL API for all or part of your schema. Currently AppSync supports one auth mode at a time though supporting multiple auth modes simultaneously is something that is being evaluated for the 2019 roadmap. In the meantime if this is something you're looking to do let me provide some options:

First, the most common solution is to use Cognito Identity and set your AppSync Authorization mode to AWS_IAM. You can then enable "unauthenticated access" in the Cognito Identity Pool which will allow the client to assume a role without logging in. You can set IAM permissions on that role for whatever parts of your GraphQL types you want to execute as outlined here: https://docs.aws.amazon.com/appsync/latest/devguide/security.html#aws-iam-authorization

Enabling UnAuthenticated access can be done with the amplify CLI when you run amplify add auth or amplify update auth and do not select the default configuration (it's disabled by default for least privilege). Alternatively you can perform this in the Cognito Identity console.

Another alternative that some customers have done is to create two GraphQL APIs, one for unauthenticated/anonymous access and one for when the user is authenticated. The unauthenticated one uses a strict subset of the schema (for example, queries only) for the other API and is configured with API key for authorization. They both use the same data sources. Your client then uses the appropriate endpoint with authentication configuration as appropriate when you call amplify.configure at which point your API.graphql calls will respect this configuration.

Hope this is helpful for the time being.

n1xn commented 5 years ago

@undefobj If I am using this method like you described with Cognito Identity and IAM permissions would I be able to use the user context within the resolvers to have fine grained access control?

Jaikant commented 5 years ago

@undefobj Thanks for your note. Creating two GraphQL API's would mean two API end points which the frontend would need to configure. ~An unnecessary complication.~ It was actually simple to hook another endpoint using apollo client. I just had to create a new ApolloClient which used the new endpoint, and passed it to the options in the query.

   options: { client: client, fetchPolicy: 'cache-and-network', errorPolicy: 'ignore', },
zirkelc commented 5 years ago

@reggie3 @GroveDev @selipso @aldarund @etwillbefine @rayhaanq to clarify, it sounds like you want to allow public access to your AppSync GraphQL API for all or part of your schema. Currently AppSync supports one auth mode at a time though supporting multiple auth modes simultaneously is something that is being evaluated for the 2019 roadmap. In the meantime if this is something you're looking to do let me provide some options:

First, the most common solution is to use Cognito Identity and set your AppSync Authorization mode to AWS_IAM. You can then enable "unauthenticated access" in the Cognito Identity Pool which will allow the client to assume a role without logging in. You can set IAM permissions on that role for whatever parts of your GraphQL types you want to execute as outlined here: https://docs.aws.amazon.com/appsync/latest/devguide/security.html#aws-iam-authorization

Enabling UnAuthenticated access can be done with the amplify CLI when you run amplify add auth or amplify update auth and do not select the default configuration (it's disabled by default for least privilege). Alternatively you can perform this in the Cognito Identity console.

Another alternative that some customers have done is to create two GraphQL APIs, one for unauthenticated/anonymous access and one for when the user is authenticated. The unauthenticated one uses a strict subset of the schema (for example, queries only) for the other API and is configured with API key for authorization. They both use the same data sources. Your client then uses the appropriate endpoint with authentication configuration as appropriate when you call amplify.configure at which point your API.graphql calls will respect this configuration.

Hope this is helpful for the time being.

I want to be able to query data on the frontend web app depending on the some user id (cognito username or identityId) and I want to insert new data from my backend lambda function. Both options sound possible, but I have the following concerns:

1) enabling unauth access means that possibly everyone on the frontend could call my APIs, so I cannot be sure that only my lambda function is calling the graphql endpoint - right? is there a possibility to enable only authenticated access with a role that allows only graphql queries resources. Then my lambda execution role gets the same role plus additional access to all resources (e.g. appsync full access)?

2) Two APIs with different auth modes, user pools for frontend and API key for backend sounds manageable. How can I configure Amplify CLI to use the same data sources (dynamodb tables) on the second API?

n1xn commented 5 years ago

I went with exactly this approach (IAM) and gave this whole lib up.

https://github.com/aws-amplify/amplify-js/issues/2363#issuecomment-449011422

mihaerzen commented 5 years ago

@NikoMontana You maybe have a code example or point me to documentation on how exactly you achieved this? I'm only interested in the client-side code, obtaining the credentials. Thank you.

dimitarrusev commented 5 years ago

@j2d2 @reggie3 @rayhaanq I'm facing the same issue right now. I'm curious, (how) did you guys solve this?

Ping @undefobj

kldeb commented 5 years ago

Another alternative that some customers have done is to create two GraphQL APIs, one for unauthenticated/anonymous access and one for when the user is authenticated....

@undefobj do you have an example of how to set this up?

I created another create react app site that i want to have anon access and added amplify as per docs. When I create a new graphql api in the front end it complains that i don't have any resolvers for my type (no @model since that will create a new table) so i removed it. If I create the graphql in the appsync console then I can't update the front end using the cli.

What am i missing?

undefobj commented 5 years ago

We're looking at putting an example together for this. As outlined above if you want to allow multiple types of access permissions on the same API, at this point you will need to use IAM as AppSync doesn't yet support multi-auth.

This statement by @chriszirkel "enabling unauth access means that possibly everyone on the frontend could call my APIs" needs clarification. Enabling unauthenticated roles in Identity Pools means the client can receive AWS credentials which are separate from the authenticated role. This allows you to assign different IAM permissions to those roles, per the link I pointed to earlier: https://docs.aws.amazon.com/appsync/latest/devguide/security.html#aws-iam-authorization

To be crystal clear, this means that you can have unauthenticated access which the IAM policy for that role can just do one thing - like run queries only. Then the other authenticated role (which could be when users log in or from a Lambda function) can do more like perform mutations. In the link I posted above note that the Resource in the policy is set on a type in your schema like so:

   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "appsync:GraphQL"
         ],
         "Resource": [
            "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/types/Query/fields/<Field-1>",
            "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/types/Query/fields/<Field-2>",
            "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/types/Mutation/fields/<Field-1>",
            "arn:aws:appsync:us-west-2:123456789012:apis/YourGraphQLApiId/types/Subscription/fields/<Field-1>"
         ]
     }
   ]
}

So you can use this to set appropriate values in the ../types/XXXXXX definition.

@aireater I would suggest you open up a new issue with details on the CLI repo as your question seems to be related to something else with your API deployment.

dimitarrusev commented 5 years ago

@undefobj How can i get access to the user's groups when using AWS_IAM auth mode?

joebernard commented 5 years ago

I would like to go the route of multiple AppSync APIs to support unauthenticated vs authenticated access. I'm stuck on how to supply two distinct Apollo profiles to Amplify (ApolloProvider), and then switch between them as the user changes auth states. Is there any good documentation of this, preferably for a React Native app? I haven't been able to find anything.

undefobj commented 5 years ago

@dimitarrusev unfortunately the Cognito User Pool groups are not available when using IAM.

manueliglesias commented 5 years ago

@joebernard

I haven't tested it, but something like this might work and help you https://codesandbox.io/s/25l7or15r

The idea is to wrap the <ApolloProvider> in a component that passes a different client depending on the auth state. Note that you might need to cleat the apollo client cache when swapping clients.

dimitarrusev commented 5 years ago

@undefobj Hey man, thanks for clearing things up. So, how should i approach this issue? Can you point me to any documentation or perhaps provide an example?

mkaschke commented 5 years ago

@All - Is there is a workaround when using AMAZON_COGNITO_USER_POOLS to have a public (non-logged in users )/private API? I couldn't find a solution so far, so I assume nobody would like to build a simple website like a blog or something with Amplify (API, Cognito)

dimitarrusev commented 5 years ago

@mkaschke As far as i know, there isn’t. You’ll have to either use AWS_IAM auth mode (check this comment) or have two API’s (one public, one private). But even then, there are far too many issues e.g. there’s no docs on how to configure two different apollo profiles based on the user’s state (see this comment), you can’t access user pool groups (see this comment) which is very important etc. My conclusion at this point is that AppSync paired with Cognito is garbage. Yes, you can build very simple apps, quickly. But, if your intention is to build complex, real world application, run away.

ngocketit commented 5 years ago

I'm running into the same trouble and the workaround I'm currently using is to have 2 APIs, one using API_KEY and the other using AMAZON_COGNITO_USER_POOLS. The first one is mostly used on the server side and the later is on the client side, where a pre-created guest account is used and logged in to enable public features.

undefobj commented 5 years ago

@ngocketit @dimitarrusev @mkaschke @aireater @mihaerzen @NikoMontana @chriszirkel @Jaikant we are looking to automate the setup of some more common admin tasks, including the IAM permissions for unauth and auth access to AWS resources such as APIs and Storage. If you could please take a look at the following RFC and leave any comments/feedback on your ideal workflows so that we can account for them in the upcoming design: https://github.com/aws-amplify/amplify-cli/issues/766

heauton commented 5 years ago

We're looking at putting an example together for this.

@undefobj An example of setting up two separate APIs would be very helpful. 🙂

mkaschke commented 5 years ago

@All :( - two thoughts / possible workarounds for discussion: First: Maybe a workaround could be to build a Route -> Lambda -> DB / Dynamodb stack for public data and use the appsync (graphsql / Cognito) just for private data (logged in users). Second: Does anyone tried googles firebase especially with authentification?

dimitarrusev commented 5 years ago

@undefobj Thanks, will do. While we’re here, can you respond to https://github.com/aws-amplify/amplify-js/issues/1252#issuecomment-456580797?

undefobj commented 5 years ago

@dimitarrusev I believe I have but perhaps the guidance has been lost in this thread. For clarity please follow the strategy to use IAM with Cognito Federated Identities here: https://github.com/aws-amplify/amplify-js/issues/1252#issuecomment-455336850

I suggest if you are unfamiliar with this process to use the Amplify CLI to create a new project and use the amplify add auth which creates a User Pool and Identity Pool, federating them both. By default an unauthenticated role will not be created for that Identity Pool but you can follow the manual amplify add auth questions to enable this. Then create an AppSync API with amplify add api and follow the directions. When you use the Amplify JS library in your app the amplify.configure('aws_exports.js') configuration step will allow your users to login with Cognito User Pools, and behind the scenes it will automatically get AWS IAM credentials for the appropriate auth or unauth role from Cognito Identity. If the user hasn't logged in yet you can get those credentials by calling Auth.currentCredentials() which will be for the unauthenticated role.

The thing that isn't automated yet, as outlined in the above comment is that you will need to:

  1. Manually in the AppSync console set the Authorization mode to IAM
  2. In the IAM console you will need to find the roles that the CLI created for the Cognito Identity Pool, and give the appropriate permissions for the unauth vs auth role.
dimitarrusev commented 5 years ago

@undefobj Hey man, again, thanks for taking the time to respond to my questions. I’m not sure if we’re on the same page here (i hope i'm not missing something) :)

Basically, i got that working (allowing access to unauthenticated and authenticated users by using AWS_IAM auth mode). However, i need to have different permissions for the authenticated users e.g. admin, author, user etc. and i'm trying to do that by putting them in a group, based on which i'll allow or deny access to specific queries and mutations.

The thing is (like you said here) that user pool groups are not available when using AWS_IAM auth mode (i can't access them in the resolver).

So my question is, how should i go about solving this issue?

undefobj commented 5 years ago

@dimitarrusev you are asking a separate question then the main issue asked in the thread (which is Public vs Private API). As you noted IAM doesn't have the concept of Groups, instead it has Roles which you'll need to "logically group" based on conditions. Amplify doesn't have tooling for this currently so you'll need to do it manually using Cognito Identity. I suggest you comment on the RFC here with your specific use case as we're looking to provide this in the coming months: https://github.com/aws-amplify/amplify-cli/issues/766 See the section entitled "Fine-grained access control by dynamically assigning roles based on Group membership or rules/token claims"

dabit3 commented 5 years ago

We're working on making this easier via the CLI, but for now you can use the following steps to allow both Authenticated & Unauthenticated access to your AWS AppSync API:

  1. Create an Amplify project
    amplify init
  2. Add auth with custom security configuration:
amplify add auth

Do you want to use the default authentication and security configuration? NO

Select the authentication/authorization services that you want to use: (Use arrow keys) User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage features for images or other content, Analytics, and more)

Please provide a friendly name for your resource that will be used to label this category in the project: YOURAPINAME

Please enter a name for your identity pool. YOURIDPOOLNAME

Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) Yes Choose defaults for the rest of the questions

  1. Add the api
amplify add api

Choose Amazon Cognito User Pool as the authorization type.

  1. Create the API
amplify push
  1. In the AppSync API dashboard settings, change the authentication type to AWS Identity and Access Management (IAM)

  2. In aws.exports.js on the client app, change aws_appsync_authenticationType to AWS_IAM

  3. In the Cognito dashboard, click "Manage Identity Pools" & click on your identity pool.

  4. Click "Edit Identity Pool" to see your "Unauthenticated role" & "Authenticated Role"

  5. Open the IAM console & find the "Unauthenticated role" from step 8

  6. Click "Add inline policy"

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "appsync:GraphQL"
            ],
            "Resource": [
                "arn:aws:appsync:<REGION>:<ACCOUNTID>:apis/<APIID>/types/Mutation/fields/listTodos"
            ]
        }
    ]
}
  1. Open the IAM console & find the "Authenticated role" from step 8

  2. Click "Add inline policy"

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "appsync:GraphQL"
            ],
            "Resource": [
                "arn:aws:appsync:<REGION>:<ACCOUNTID>:apis/<APIID>/types/Mutation/fields/listTodos",
                "arn:aws:appsync:<REGION>:<ACCOUNTID>:apis/<APIID>/types/Mutation/fields/createTodo"
            ]
        }
    ]
}
  1. In index.js, add this code:
import { Auth } from 'aws-amplify'
Auth.currentCredentials()
  .then(d => console.log('data: ', d))
  .catch(e => console.log('error: ', e))
  1. You should now be able to query when logged out, & query & create mutations when logged in.

If you'd like to access the unique identity of the logged in user for user authorization & fine grained access control, you can access the $context.identity.cognitoIdentityId) in the resolver.

undefobj commented 5 years ago

All - Please see @dabit3 instructions above or the sample we posted here: https://github.com/dabit3/appsync-auth-and-unauth

As mentioned before we are looking to make this easier with CLI tooling in the following RFC: https://github.com/aws-amplify/amplify-cli/issues/766 For the short term hopefully this helps you get up and running.

vparpoil commented 5 years ago

[edited] - found the answer

I ran into the same issue, which is really blocking in a real use of amplify to build an app. It make me really question the choice we made of using amplify... I just tried the proposal given above in order to allow unauthenticated users to run a mutation with the following : update: worth to mention that the MutationName bellow can be found in the aws console > AppSync > schema > find the mutation type and look at the keys of the object.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "appsync:GraphQL"
            ],
            "Resource": [
                "arn:aws:appsync:<REGION>:<CLIENTID>:apis/<APIID>/types/Mutation/fields/MutationName"
            ]
        }
    ]
} 

Here is my JS - I had an error here when calling graphqlOperation, I had updated the code with the correction :

Auth.currentCredentials().then(response => {
            API.graphql(graphqlOperation(MutationName, {input: input})).then(response => console.log(`response: ${response}`))
                .catch(error => console.log(error));
        })

And I always get a GraphQLError : "Request failed with status code 401". => now this is ok

mkaschke commented 5 years ago

@vparpoil - it is still not working right?

vparpoil commented 5 years ago

@mkaschke It's working now. I can get a unauthenticated user to run a graphql mutation using this setup

vparpoil commented 5 years ago

Another issue with this setup that happens to me : when running amplify push, the aws-exports.js file is overwritten and the aws_appsync_authenticationType switch back to AMAZON_COGNITO_USER_POOLS, resulting in 403 errors. It's quite annoying, but is it a bug or a feature ?

selipso commented 5 years ago

While the above setup instructions by @dabit3 work when using API.graphql, when following the following example from Amplify, the same no current user error occurs. The difference is that API.graphql uses Amplify's GraphQL client whereas the code snippet below uses the Appsync GraphQL client.

const result = await client.mutate({
    mutation: gql(createTodo),
    variables: {
      input: {
        name: 'Use AppSync',
        description: 'Realtime and Offline',
      }
    }
  });
selipso commented 5 years ago

After hours of struggling with converting my Cognito code to IAM, I've found the solution with migrating to AppSync with IAM. The angular-chat-starter repository helped, but I had to make a few changes.

Example source code for doing a mutation:

this.appsync.hc().then(
      client => {
        console.log('Received client. Mutating...');
        console.log(client);
        return client.mutate({
          mutation: gql(createTodo),
          variables: {
            input: {
              name,
              active: true
            }
          }
        }).then(({ data }) => {
          console.log('mutation complete', data);
        }).catch(err => console.log('Error creating classroom', err));
      }
    )

The above code is very similar to the app sync chat starter. However the chat starter uses Cognito. To use IAM, you have to initialize the AWSAppsyncClient() with different auth params, like so:

export class AppsyncService {
  // hc;
  _hc;

  constructor() {
    const client = new AWSAppSyncClient({
      url: aws_exports.aws_appsync_graphqlEndpoint,
      region: aws_exports.aws_project_region,
      auth: {
        type: AUTH_TYPE.AWS_IAM,
        credentials: () => Auth.currentCredentials()
      }
    });
    // this.hc = client.hydrated;
    this._hc = client;
  }
  hc() {
    return this._hc.hydrated();
  }
}

Works cleanly and with offline handling capabilities (yet to test those)

jordanranz commented 5 years ago

I am going to go ahead and close this as the original question seems to have been answered. Please reopen if you are experiencing any related problems.

gl2748 commented 5 years ago

@dabit3 One thing i would add to your how-to (which was very helpful btw - thanks!) is that for the unauthenticated role policy that you describe:

 "arn:aws:appsync:<REGION>:<ACCOUNTID>:apis/<APIID>/types/Mutation/fields/listTodos"

I think you meant types/Query/fields/listTodos - note Query and not Mutation.

That's it!.

For others working through this, the following were helpful tidbits.

It's worth noting that the IAM permissions on the AppSync 'DataSources' config, under

Create or use an existing role
Allow AWS AppSync to securely interact with your data source.

Are distinct from the IAM roles configured to interface the Cognito Users with Appsync, I'd suggest not editing or recreating these roles after your initial amplify api create.

gl2748 commented 5 years ago

@vparpoil regarding the way aws_appsync_authenticationType is overridden you can do this to preserve your change outside editting the aws-exports.js directly.

const aws_exports_override = {...aws_exports, aws_appsync_authenticationType: "AWS_IAM",}
Amplify.configure(aws_exports_override);
rudyhadoux commented 5 years ago

Hi @elorzafe, Amplify-CLI does not allow unauth configuration anymore ??? So, how to allow unauthentified users ?

rudyhadoux commented 5 years ago

I have found the answer here : https://stackoverflow.com/questions/53766100/how-to-properly-handle-unauthenticated-users-and-requests-in-aws-amplify-appsync

dabit3 commented 5 years ago

@rudyhadoux we've also added first class support for multiple authentication / authorization types in the CLI. Here's the release blog -> https://aws.amazon.com/blogs/mobile/using-multiple-authorization-types-with-aws-appsync-graphql-apis/

rudyhadoux commented 5 years ago

OK thanks @dabit3. It is easier to test within apps without authentication...