Skip to content
This repository has been archived by the owner on Apr 14, 2023. It is now read-only.

Full-stack tutorial: Incorrect way of setting authorization header in ApolloClient #1159

Open
98lenvi opened this issue May 1, 2021 · 0 comments

Comments

@98lenvi
Copy link

98lenvi commented May 1, 2021

Hi all, great work with the full-stack tutorial. I wanted to learn basic GraphQL + Apollo quickly and the tutorial helped me a lot.
But I came across an issue with the way the authorization header is set in the ApolloClient in the tutorial(Frontend - React).

Edit: I think this might have been done on purpose to keep the tutorial short and not overwhelm new users.

const client: ApolloClient<NormalizedCacheObject> = new ApolloClient({
  cache,
  uri: 'http://localhost:4000/graphql',
  headers: {
    authorization: localStorage.getItem('token') || '',
    'client-name': 'Space Explorer [web]',
    'client-version': '1.0.0',
  },
  typeDefs,
  resolvers: {},
});

Above, the ApolloClient is initialized with the value of token present in the localStorage at the time of initialization. But in most cases, the user isn't logged in and the authorization is initialized with no value. If the user logs in later and the value of token gets populated in the localStorage, the client has no way of getting the present value of token from the localStorage. i.e. the authorization sent in the header is still undefined, and when booking the trips in the cart, we get the following error.

{"errors":[{"message":"Cannot read property 'id' of null","locations":[{"line":2,"column":3}],"path":["bookTrips"],"extensions":{"code":"INTERNAL_SERVER_ERROR","exception":{"stacktrace":["TypeError: Cannot read property 'id' of null","    at UserAPI.bookTrips...

A fix for this is fairly simple, If we set the header according to the documentation here. The latest value of the token is always fetched from the localStorage with every request.

const httpLink = createHttpLink({
  uri: 'http://localhost:4000/graphql',
});

const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('token');
  return {
    headers: {
      ...headers,
      authorization: token || "",
    }
  }
});

const client: ApolloClient<NormalizedCacheObject> = new ApolloClient({
  cache,
  link: authLink.concat(httpLink),
  typeDefs,
  resolvers: {},
});

^ The above worked for me, as I am new to Apollo, please suggest a better way if possible.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant