1
votes

So I am trying to pass an authorization header to Apollo Client 3 to access a database. The recommended way to do this in the current docs is to create a HttpLink object

const httpLink = new HttpLink({
  uri: "************************",
  fetch
});

and then use the setContext method (from 'http-link-context' I think):

const authLink = setContext((_, { headers, ...context }) => {
  const token = localStorage.getItem("userToken");
  return {
    headers: {
      ...headers,
      ...(token
        ? { Authorization: `Bearer ${token}` }
        : `Bearer *************************`)
    },
    ...context
  };
});

then graft the objects together and pass them as a "link" object to the new ApolloClient :

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: authLink.concat(httpLink)
});

Unfortunately, though, when I do this I get an error message

Uncaught (in promise) Error: GraphQL error: Missing authorization header.

And when I inspect my request headers I cannot see an authorization header.

Has anyone else been able to get this up and running successfully?

3

3 Answers

2
votes

Very annoyingly the example they give in Apollo's docs do not show the import for setContext so the package required should not be imported from "http-link-context" but instead from "@apollo/link-context" when using the latest version of Apollo (or Apollo 3, anyway). Using the current package it works fine.

2
votes

I think they updated there documentation that includes setContext:

    import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client';
    import { setContext } from '@apollo/client/link/context';
    
    const httpLink = createHttpLink({
      uri: '/graphql',
    });
    
    const authLink = setContext((_, { headers }) => {
      // get the authentication token from local storage if it exists
      const token = localStorage.getItem('token');
      // return the headers to the context so httpLink can read them
      return {
        headers: {
          ...headers,
          authorization: token ? `Bearer ${token}` : "",
        }
      }
    });
    
    const client = new ApolloClient({
      link: authLink.concat(httpLink),
      cache: new InMemoryCache()
    });

You don't need to install @apollo/link-context separately anymore, everything is now bundled with apollo 3.0. [Reference]: https://www.apollographql.com/docs/react/networking/authentication

1
votes

first apollo-link-context is now @apollo/client/link/context

second: u can use headers in apolloclient

const client = new ApolloClient({
    cache,
  uri: 'http://localhost:4000/graphql',
  headers: {
    authorization: localStorage.getItem('token') || '',
    'client-name': 'Space Explorer [web]',
    'client-version': '1.0.0',
  },
  // or authLink because its return Headers
  ...authLink
});