Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticate Apollo Client to AWS AppSync with Cognito User Pools

I am trying to connect to my AWS AppSync API using the plain Apollo Client but I am not sure how to structure the authentication header correctly.

So far I have followed the header authentication documentation here: https://www.apollographql.com/docs/react/recipes/authentication.html

And have this code, which I adapted to include the token call to the Amplify authentication service but it returns a 401 error:

const httpLink = createHttpLink({
  uri: '[API end point address]/graphql'
});

const authLink = setContext((_, { headers }) => {
  const token = async () => (await Auth.currentSession()).getAccessToken().getJwtToken();
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : ""
    }
  }
})

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache()
})

The only documentation I can find relating to this doesn't provide any technical instructions:

When using Amazon Cognito User Pools, you can create groups that users belong to. This information is encoded in a JWT token that your application sends to AWS AppSync in an authorization header when sending GraphQL operations.

From here: https://docs.aws.amazon.com/appsync/latest/devguide/security.html

I know that token is fine because if I use the AppSync JavaScript API then it works. Is there anywhere I can go to find out how to achieve this or does someone know how?

Edit:

So far i have tried changing this line:

  authorization: token ? `Bearer ${token}` : ""

The following attempts:

token

jwtToken: token

authorization: token

Authorization: token

None of these have worked either.

like image 623
Exitialis Avatar asked Sep 07 '18 17:09

Exitialis


People also ask

Can I use Apollo client with AppSync?

We have now explored this issue further. The reason to use AppSync over just the ApolloClient is if you need the offline capability. We wrote our own Rehydrated and got around the issues there but then when posting a mutation, it got enqueued in redux-offline but never processed.

How do you authenticate using Cognito?

Go to AWS Cognito service and click “Manage Identity Pools”. 2. Enter “Identity pool name”, expand the “Authentication providers” section and select “Cognito” tab. This is where the Cognito authentication provider will be registered with the Identity pool.

Can AWS Cognito be used for authorization?

Amazon Cognito allows you to use groups to create a collection of users, which is often done to set the permissions for those users. In this post, I show you how to build fine-grained authorization to protect your APIs using Amazon Cognito, API Gateway, and AWS Identity and Access Management (IAM).


2 Answers

Disclaimer: Never tried it, but here is what I would do:

Check out the AppSync Client code here as a foundation for creating a an Authentication link for Apollo Client and the AppSync server. It looks like that code provides the scaffolding for each of the available authentication methods.

Specifically, if you are trying to use the OPENID_CONNECT method of authentication, it appears as if the JWT token does not need to be prepended by Bearer (line 156).

like image 130
Jclangst Avatar answered Sep 28 '22 07:09

Jclangst


You can see an example of it on Github from AWS sample. Works with AppSync but very similar.

// AppSync client instantiation
const client = new AWSAppSyncClient({
  url: GRAPHQL_API_ENDPOINT_URL,
  region: GRAPHQL_API_REGION,
  auth: {
    type: AUTH_TYPE,
    // Get the currently logged in users credential.
    jwtToken: async () => (await Auth.currentSession()).getAccessToken().getJwtToken(),
  },
  // Amplify uses Amazon IAM to authorize calls to Amazon S3. This provides the relevant IAM credentials.
  complexObjectsCredentials: () => Auth.currentCredentials()
});

Link to the AWS repo

like image 21
Marc-Olivier Blouin Avatar answered Sep 28 '22 06:09

Marc-Olivier Blouin