Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't set Authentication header for Apollo client

I'm working on a Laravel application that uses React and Redux on the client side, with the React preset and Mix. I've decided to try out GraphQL for the API rather than the usual REST API approach and it's working OK so far. However, I've now got stuck.

I'm using Apollo as my HTTP client since it's built for working with GraphQL. In the past I've used JWT Auth for securing APIs, so naturally I've gone for that approach here too, since implementation is just a case of adding an appropriate header. I've followed the instruction on setting headers with Apollo, but the headers aren't getting set. Here's the JS file in question:

import LinkList from './components/LinkList';
import React from 'react';
import ReactDOM from 'react-dom';
import {Container} from './container';
import {createStore} from 'redux';
import reducer from './reducer';
import {Provider} from 'react-redux';
import {fromJS} from 'immutable';
import ApolloClient from 'apollo-boost';
import gql from 'graphql-tag';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';

const httpLink = createHttpLink({
    uri: window.initialData.graphql_route
});

const authLink = setContext((_, { headers }) => {
    const token = window.initialData.jwt;
    // 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()
});

client.query({
    query: gql`{
        links {
            id
            title
            link
        }}`
}).then(result => console.log(result));

const store = createStore(
    reducer,
    fromJS(window.initialData),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

if (document.getElementById('list')) {
    ReactDOM.render(
        <Provider store={store}>
            <Container />
        </Provider>,
        document.getElementById('list')
    );
}

I populate window.initialData in the view, and that contains the necessary data, including the JWT token as window.initialData.jwt. Setting a breakpoint inside the definition of authLink does nothing, implying that it never gets called.

Any idea what's gone wrong? I've followed the examples in the documentation pretty closely, so all I can think of is that they might be put of date.

like image 556
Matthew Daly Avatar asked Dec 14 '22 16:12

Matthew Daly


1 Answers

Info: Don't save your token in the localStorage Is it safe to store a JWT in localStorage with ReactJS?

You are using the ApolloClient from 'apollo-boost', but your token configuration is for another ApolloClient, the { ApolloClient } from 'apollo-client'.

If you want to save the token using the ApolloClient from apollo-boost:

const client = new ApolloClient({
  uri: ...,
  request: async operation => {
    const token = localStorage.getItem('token');
    operation.setContext({
      headers: {
        authorization: token ? `Bearer ${token}` : ''
      }
    });
   }
});

Apollo Boost migration

like image 195
Alex Munoz Avatar answered Jan 29 '23 11:01

Alex Munoz