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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With