Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Public queries and mutations (no authentication)

The documentation says there are 3 ways we can authorise an application to interact with the API, but it doesn't look like there is a way of having a public endpoint.

For example, if I want anyone to query a list of todos, but only authenticated users can add a todo to that list, how can I achieve this?

Or if I want to allow anyone to do a schema introspection, but restrict all other queries to authenticated users, is it possible?

I'm using cognito for authentication. I noticed there is a AppId client regex field that says (Optional) Type a regular expression to allow or block requests to this API. but I can't find any example unfortunately. Maybe this is what I'm looking for?

Thanks

Julien

like image 310
Julienmachon Avatar asked Jan 09 '18 18:01

Julienmachon


People also ask

Should GraphQL handle authentication?

Your GraphQL API probably needs to control which users can see and interact with the various data it provides. Authentication is determining whether a given user is logged in, and subsequently determining which user someone is. Authorization is then determining what a given user has permission to do or see.

How do you authenticate in GraphQL?

Authenticating GraphQL is quite simple. We make use of queries and mutations. For a user to have access he has to register first, that's why we have register pages on almost all websites. The registration hits a particular endpoint, for example, it is usually like this https://URL_HERE/register API in a REST endpoint.


1 Answers

There are couple of ways in which you can do this based on Authentication mechanism.

Say you are using Cognito Identity and using AWS IAM flow for authentication. Then you would have 2 policies one for Authenticated User and One for Unauthenticated User.

Given a GraphQL Schema

schema{
   query:Query
   mutation:Mutation
}

type Query{
   listTodo(count:Int, paginationToken:String):[TodoConnection];

}

type Mutation{
   addTodo(input:TodoInput):Todo
}

Your Unauthenticated policy would look something like

{
  "Version": "2012-10-17",
  "Statement": [
  {
     "Effect": "Allow",
     "Action": [
        "appsync:GraphQL"
     ],
     "Resource": [
        "arn:aws:appsync:us-west-2:<account-id>:apis/<api-id>/types/Query/fields/listTodo", 
        //-> below is for schema introspection
        "arn:aws:appsync:us-west-2:<account-id>:apis/<api-id>/types/Query/fields/__schema" 
     ]
    ]
   }
}

Your authenticated user policy would look like

{
  "Version": "2012-10-17",
  "Statement": [
  {
     "Effect": "Allow",
     "Action": [
        "appsync:GraphQL"
     ],
     "Resource": [
        "arn:aws:appsync:us-west-2:<account-id>:apis/<api-id>/types/Mutation/fields/addTodo",
        "arn:aws:appsync:us-west-2:<account-id>:apis/<api-id>/types/Query/fields/listTodo", 
        //-> below is for schema introspection
        "arn:aws:appsync:us-west-2:<account-id>:apis/<api-id>/types/Query/fields/__schema"
     ]
    ]
   }
}

If you are using JWT Tokens then you will have to associate each Cognito User Pool User with a Group (like "Admin", "Users" etc). You then will have to associate each of the query/mutation with the Cognito Groups that can perform the operation using AWS AppSync auth directives. To do you you will only need to update the schema like below:

schema{
   query:Query
   mutation:Mutation
}

type Query{
   listTodo(count:Int, paginationToken:String):[TodoConnection];
     @aws_auth(cognito_groups:["Users", "Admin"])
}

type Mutation{
   addTodo(input:TodoInput):Todo
     @aws_auth(cognito_groups:["Admin"])
}

API Key based authentication, its not possible to have control over the operation.

like image 165
Karthik Avatar answered Oct 02 '22 15:10

Karthik