Refreshing Token Based Authentication With Apollo Client 2.0

Lucas McGartland
3 min readDec 21, 2017
Apollo Client 2.0 provides many great features out of the box

If you use GraphQL, you’ve probably heard of Apollo Client. Apollo is fantastic for React projects because it can be incrementally adopted, has a great community, and great documentation. However, with the release of Apollo Client 2.0, there were some breaking changes, including the method of extending the interface to support your own access token/refresh token authentication flows.

A common method of authentication on the web is JSON Web Tokens (JWT). A user logs in using their username and password, and gets an access token and refresh token in response. The client then uses the access token for any requests with the server after that for authentication instead of the user’s password. Eventually, the access token will expire, and the user will need a new one. Refresh tokens allow the client to get a new access token without forcing the user to reauthenticate with their username and password.

Usually access tokens expire after an amount of time elapses, but the server can also expire them before that. So any request the client makes needs to be able to handle the scenario of an expired access token. We came up with this flow to handle it:

Re-authentication Flow for Requests

  1. Request is rejected with error message.
  2. Refresh token is used to fetch new access token.
  3. Request is retried with new access token.

In practice, Apollo will handle making the actual requests to the server for you, letting you focus on your queries. However, to implement the re-authentication flow, we’ll need to extend that request making process, the network interface. In our research, we found an example of someone who overrode the network interface with their own version of the flow above for Apollo Client 1.0. However, the network interface is no longer exposed in Apollo Client 2.0.

Using Apollo Client 2.0 ‘Links’ to extend the interface

The new method of extending the Apollo Client network interface is through what they call links. Here’s what the Apollo docs say about links:

“Apollo Link is designed to be a powerful way to compose actions around data handling with GraphQL. Each link represents a subset of functionality that can be composed with other links to create complex control flows of data.”

What links allow you to do is create a set of functions that can interact and manipulate your request before it gets sent off to be fetched. Here is the example from the Apollo docs that creates a link to inject an authorization header into your request.

An Apollo Client can be composed of many links. However, the set of links must always end with a terminating link. Unlike the preceding links, the terminating link has to execute some operation from the parameters and return the results of the operation. Usually, this operation is a network request.

The default terminating link that Apollo provides is apollo-http-link. This terminating link executes the network request using fetch and sends back the result. You can create the link using the createHttpLink() function provided from the apollo-http-link package. createHttpLink() can take a number of options, which you can find here. In the example above, we pass the URI for the graphql server so it knows where to send the request.

Implementing the Re-Authorization Flow

To implement the re-authozation flow listed above, we can override the fetch executed by the terminating link. We create a customFetch function that can execute the request and retry with a new token if it fails and pass that as an option to the apollo-http-link.

const httpLink = createHttpLink({
uri: "/graphql",
fetch: customFetch
})

Here’s how we implemented a customFetch function and added it to the Apollo-Client:

Now when a request is executed, it checks for a unauthorized error before returning the results. If the user has an expired access token, the link will get a new one using a refresh token and retry the request.

Closing Words

Hopefully this example helps you implement refresh token based re-authentication in your Apollo Client. Comment below if you have trouble getting this example to work and I’ll do my best to get back to you as quickly as possible!

If you want to talk more, let me know what you think about the new Star Wars, or whatever, hit me up on Twitter @lucasmcgartland.

--

--

Lucas McGartland

Inaugural class @USCIovineYoung • Co-Founder, CPO @thebeeinc • Innovation/design @viasatinc • www.lucasmcgartland.com