GOAL
I want to populate my Authorization
header with an access token. I want to store that access token in the Apollo cache as Auth0 explicitly state not to store access tokens in local storage (I don't know why the Apollo Client docs seem to think it's okay).
Failing that, I want to store my access token securely and be able to add it to each Apollo Client request to the Apollo Server.
const apolloClient = withApollo(({ctx, headers, initialState}) => {
const cache = new InMemoryCache();
// Code here to access local cache.
return new ApolloClient({
cache,
link: new HttpLink({
uri: <apollo server endpoint>,
headers: {
Authorization: `Bearer ${accessToken}`,
'Access-Control-Allow-Origin': 'http://localhost:3000/',
...headers
},
credentials: 'include'
}),
typeDefs,
resolvers
})
})
class MyApp extends App {
render() {
const { Component, pageProps, apollo } = this.props;
return (
<ApolloProvider client={apollo}>
<Component {...pageProps} />
</ApolloProvider>
);
}
}
export default apolloClient(MyApp);
TRIED
localStorage
from within the withApollo
function but it is SSR'd so I'm unable to access that. I was going to use the localStorage
to set a boolean to check in the withApollo
function so it'll know the access token has been added to the apollo cache after the redirect.Authorization
header. But I was getting issues with setting the initial state overriding the cache set in sign in function.OTHER IDEAS
I thought I could pass the access token through in the ctx
argument, but I'm not familiar enough with Next.js to figure out if that's valid way to do it.
I thought I could pass in a props to the withApollo
function from a component, but that doesn't seem like it'd be possible.
QUESTIONS
fetch
polyfill, would that be appropriate for this situation? If so, how would that work?withApollo
HOC work and why is it needed to work with Next.js? I've read some of the code behind this, but I don't fundamentally understand why it is needed.I was able to find a solution to my question. I just didn't fully understand the Apollo Client and how to use all of the required packages.
SOLUTION
I used setContext
from the apollo-link-context
library. It's part of the link
set of libraries that Apollo Client offers to customise the network request after a graphql operation has started. I set the header in the setContext
function. Like so:
const authLink = setContext((_, { headers }) => {
// It is also possible to use the local storage method in here.
const data = cache.readQuery({
query: ACCESS_TOKEN
});
return {
headers: {
...headers,
authorization: accessToken ? `Bearer ${data.accessToken}` : ""
}
}
});
The following is outside the withApollo
function.
const httpLink = new HttpLink({
uri: '<server uri>',
});
The following is inside the withApollo
function.
return new ApolloClient({
cache,
link: authLink.concat(httpLink),
typeDefs,
resolvers
})
The docs for how setContext
are here and the docs for the `apollo-link-context' are here.