» » Apollo Client GraphQL Authentication with AWS Cognito

Apollo Client GraphQL Authentication with AWS Cognito

posted in: Dev Notes | 0

In my previous React/Redux approach, the authentication state and data flow were completely managed by Redux.

For simplicity and portability, my advocation of shifting RESTful endpoint to GraphQL succeeded. We set up a GraphQL server on Node to replace the Python endpoint while keeping discrete APIs on some data-intensive workload for visualization, as well as server-side rendering.

A discrete authentication service is required then. For efficiency, we are adopting the AWS Cognito for user pool management and shift the authentication service to AWS Amplify.

We did make some trial and error, I think it is worth to share it.

AWS Amplify is designed to give a declarative interface to the client development. We can quickly add features such as User SignUp/SignIn, MFA, tracking or metric analytics. One Challenge is the integration with the GrapQL, and yet we do not want to get our feet too deep in the AWS ecosystem.

Our Apollo client is served with  Apollo Provider:

Working Case: Authentication of Apollo Client with Redux

The Apollo Client documentation provides us with simple workflow by introducing the `setContext` method on the ApolloClient link.

See more at the documentation: https://www.apollographql.com/docs/react/recipes/authentication.html#Header

In previous React/Redux approach, since `store.getState()` is a pure function it returns the authToken in synchroneity.

Also, the authToken updates itself as the `store.getState()` function is called every time the authToken is retrieved. It just works simply and easily.

Wrong Attempt: Adding Authenticaiton header with setContext on ApolloLink

Apollo Client introduces us with the `apollo-link-context` add-on modules and SetContextLink method

See More: How to do authentication with ApolloClient 2.0? · Issue #2168

The problem is that `Auth.currentSession()` returns a promise, which runs asynchronously. The function within `setContext` is run asynchronously to cater the resolution of currentSession.

However, the rendering of the app is not asynchronous. Since the app is initialized right away with the Apollo Client Provider, there will be a problem when the client provider is injected to the React App prior to the retrieval of `current Session`.

This approach works partially if we update our user authentication session through the in-app sign in or sign out, as the `currentSession` can be retrieved right in time. However, if we refresh the browser, `authLink` cannot get the tokens it needs. As the retrieval of session data takes time.

Working Approach: Refactor Fetch method

Since authentication credentials can change dynamically, it is better to retrieve session upon every GraphQL requests. A fetch middleware is applied:

In summary, Apollo client has provided with a lot of functionality, with various ways to re-factor the usage. It also handles things like caching, making sure data is not duplicated, and sending said data to your front-end library of choice.

Leave a Reply

Your email address will not be published. Required fields are marked *