This article has come together after months of trying different implementations and discovering more layers to using Auth0 and Apollo. Even though I am sure that some of the principles will work well with other similar libraries. I don’t want to take credit for this approach since it was pulled together from multiple forums, GitHub issues, and articles.
For this code, I am using the relatively new auth0-react library, but this solution can be used with their auth0-spa SDK. In trying to use an authenticated graphQL server with apollo client / auth0 /react based on the tutorials, one of the issues that never seemed to be addressed was a clean way of getting the tokens and if the tokens were expired to update the token and retry the query/mutation seamlessly.
Most of the solutions seemed to be pulling the token from local storage authentication. Still, if you had an expired token, the only solution offered was to delete the expired token and log the user out. The initial break came from mattwilson1024 in the auth0 forum.
AuthorizedApolloProvider.tsx
import { ApolloClient, ApolloProvider, createHttpLink, InMemoryCache } from '@apollo/client';
import { setContext } from '@apollo/link-context';
import React from 'react';
import { useAuth0 } from '../react-auth0-spa';
const AuthorizedApolloProvider = ({ children }) => {
const { getTokenSilently } = useAuth0();
const httpLink = createHttpLink({
uri: 'http://localhost:4000/graphql', // your URI here...
});
const authLink = setContext(async () => {
const token = await getTokenSilently();
return {
headers: {
Authorization: `Bearer ${token}`
}
};
});
const apolloClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
connectToDevTools: true
});
return (
<ApolloProvider client={apolloClient}>
{children}
</ApolloProvider>
);
};
export default AuthorizedApolloProvider;