When the backend responds, the headers should include:
Access-Control-Expose-Headers: *
// or the name of your refreshToken field
Here you have the full code:
Front-end: (Apollo & React)
const httpLink = new HttpLink({ uri: URL_SERVER_GRAPHQL })
// Setup the header for the request
const middlewareAuthLink = new ApolloLink((operation, forward) => {
const token = localStorage.getItem(AUTH_TOKEN)
const authorizationHeader = token ? `Bearer ${token}` : null
operation.setContext({
headers: {
authorization: authorizationHeader
}
})
return forward(operation)
})
// After the backend responds, we take the refreshToken from headers if it exists, and save it in the cookie.
const afterwareLink = new ApolloLink((operation, forward) => {
return forward(operation).map(response => {
const context = operation.getContext()
const { response: { headers } } = context
if (headers) {
const refreshToken = headers.get('refreshToken')
if (refreshToken) {
localStorage.setItem(AUTH_TOKEN, refreshToken)
}
}
return response
})
})
const client = new ApolloClient({
link: from([middlewareAuthLink, afterwareLink, httpLink]),
cache: new InMemoryCache()
})
In the backend (express).
If we need to refresh the token (e.g: because the actual one is going to expire)
const refreshToken = getNewToken()
res.set({
'Access-Control-Expose-Headers': 'refreshToken', // The frontEnd can read refreshToken
refreshToken
})
Documentation from: https://www.apollographql.com/docs/react/networking/network-layer/#afterware