mastercooler6
mastercooler6

Reputation: 467

Token in LocalStorage is there but not being put inside my Axios Instance

One of my components is not loading because the token in Local Storage is not being sent in my Axios request.

Here is the flow. I have a Login component that sets the token in Local Storage once the user has been Authenticated. Here is that function:

   AuthService.authenticateEmployee(employee).then((r) => {
      if (r != null && r.data.jwt != null) {
        localStorage.setItem("token", r.data.jwt);
        console.log(r.data.jwt);
        console.log("nav to tickets now");
        this.props.history.push("/tickets");
      }
    });
  };

It then takes you to /tickets which is where my problem lies. The TicketsComponent tries to validate the token. If its invalid then it should redirect the user back to the login page.

   AuthService.validateToken()
      .then((res) => {
        console.log("step 1");
        if (res == undefined || res == null || !token) {
          this.props.history.push("/login");
        }
      })
      .then(() => {
        console.log("step 2");

        TicketService.getTickets().then((res) => {
          if (this._isMounted) {
            this.setState({ tickets: res.data });
          }
        });
      });

Here is validateToken():

  validateToken() {
    console.log(" about to try validating");
    return AxiosInstance.get("authenticate")
      .then("did it")
      .catch((err) => console.log(err));
  }

And finally, this is where I have pinpointed the problem to:

const AxiosInstance = axios.create({
  baseURL: API_BASE_URL,
  headers: { Authorization: `Bearer ${getTokenFromLocalStorage()}` },
});

function getTokenFromLocalStorage() {
  const token = localStorage.getItem("token");
  console.log("the token from local storage is -> " + token);
  if (token === null) {
    return undefined;
  }
  return token;
}

export default AxiosInstance;

If I hardcode the value of the Authorization header to have the same token that is in LocalStorage, then it works. But not when I try to use the getTokenFromLocalStorage function. The function does not even seem to get called. The console.log() is not being printed at all. What is going on? How can I embed my token into this request correctly?

EDIT: I double checked my LocalStorage in developer tools. It was empty before clicking the login button. When I click login, then the token gets populated as it should as seen here: localStorage However, it still failed to log me in. errors

IMPORTANT: So it seems like my getTokenFromLocalStorage only gets called when the Axios Instance is created and not each time it’s used. How can I fix this so that the function gets called every time I use the AxiosInstance?

UPDATE: I found out that the token is definitely not being retrieved from getTokenFromLocalStorage since this is the header being sent in the request: Request Header

However, I can call localStorage.getItem("token") from inside the TicketsComponent AFTER clicking login and AFTER setting the token in the header and it displays the correct token. And I posted an image showing that the token is being set in LocalStorage after clicking login so what's going on?

UPDATE #2: I found this StackOverflow answer but it is of no use for me. Anyone have any ideas? LINK

Upvotes: 2

Views: 2922

Answers (1)

mastercooler6
mastercooler6

Reputation: 467

I figured it out. The solution was to use interceptors, a part of Axios Instances. Using interceptors allows you to dynamically set the header for each request since it can change at any time.

const AxiosInstance = axios.create({
  baseURL: API_BASE_URL,
});

AxiosInstance.interceptors.request.use(function (config) {
  // Do something before request is sent
  let token = localStorage.getItem("token");
  config.headers["Authorization"] = "Bearer " + token;
  return config;
});

export default AxiosInstance;

And then it worked.

Upvotes: 5

Related Questions