88dax
88dax

Reputation: 307

Not able to retrieve the updated token from localStorage in ApolloClient

I'm implementing React Authentication with ApolloGraphQL.

Context:
In signin.js, I'm generating the token when user clicks submit button and set it to the Localstorage.
Then, I'm retrieving the token in App.js to I can pass it to GraphQL, so that, it can be retrieved in in server.js.

Problem:
After user clicks the submit button, I can see the newly generation token in: Developer Tools > Application > Local Storage. But it returning 'null' for 'client side token' in App.js
When I do the signin again, I'm seeing the previously generated token as the value of 'client side token', which means its not getting the updated token from the LocalStorage.

Obviously, because of this, 'server side token' is null for the first time and returning the previously generated token for the second time signin.

app/client/src/components/signin.js:

    handleSubmit = (event, SignIn)  => {
        event.preventDefault();
        SignIn().then(({ data }) => {
                localStorage.setItem('token', data.SignIn.token);
                this.clearState();
        })
    }  

app/client/src/app.js:

  //initiating the ApolloClient
const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',

  fetchOptions: {
    credentials: 'include'
  },
//adding token to the localstorage
  request: operation => {
  const token = localStorage.getItem('token');

  operation.setContext({
      headers:{
          authorization: token
      }
    })
    console.log(`client side token ${token}`);
   },
 //catching the most common network error, if any
  onError: ({ networkError }) => {
    if(networkError){
      console.log('Network Error', networkError);
      }
  }
});

server.js:

const app = express();
app.use(async (req, res, next) => {
const token = req.headers['authorization'];
console.log(`server side token: ${token}`);
  next();
});

Upvotes: 1

Views: 1596

Answers (1)

isubasti
isubasti

Reputation: 21

you need somekind of auth middleware as request in apollo client is only getting called on construction i believe which is why the localStorage has the previous token when you reload the page.

import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { ApolloLink, concat } from 'apollo-link';

const httpLink = new HttpLink({ uri: '/graphql' });

const authMiddleware = new ApolloLink((operation, forward) => {
  // add the authorization to the headers
  operation.setContext({
    headers: {
      authorization: localStorage.getItem('token') || null,
    }
  });

  return forward(operation);
})

const client = new ApolloClient({
  link: concat(authMiddleware, httpLink),
});

see https://www.apollographql.com/docs/react/advanced/network-layer/#middleware for more details

Upvotes: 2

Related Questions