Reputation: 467
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
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