I used to write the API Url inside the request like this:
export const getAllAdmins2 = () => dispatch => {
axios
.get("http://baseUrl:3083/api/admin/getAllAdmins")
.then(retrievedAdmins => {
console.log("getAllAdmins2");
console.log(retrievedAdmins);
// this.setState({
// usersInformation: retrievedAdmins.data
// });
})
.catch(error => console.log(error));
};
But, this could be improved by setting the URL in a separate file :
conf/api.js
import axios from "axios";
export default axios.create({
baseURL: `http://baseUrl:3083`
});
And so I changed the API request to this:
import API from "../conf/api";
export const getAllAdmins = () => dispatch => {
API.get("api/admin/getAllAdmins")
.then(retrievedAdmins => {
console.log("retrievedAdmins insideAPI.get(api/admin/getAllAdmin)");
console.log(retrievedAdmins);
// this.setState({
// usersInformation: retrievedAdmins.data
// });
})
.catch(error => console.log(error));
};
But, this caused a strange problem: The code that was responsible for automatically setting the authentication token in each request no longer does its job. In the backend, the token is undefined:
2020-02-28T17:49:41+0100 <notice> TokenServices.js:76 Object.HasValidToken Access Token:undefined
This is the code that's responsible for setting the authentication header:
App.js
if (localStorage.jwtToken) {
// Set auth token header auth
setAuthToken(localStorage.jwtToken);
// Decode token and get user info and expiration
const decoded = jwt_decode(localStorage.jwtToken);
// Set User and is Authenticated
store.dispatch(setCurrentUser(decoded));
// Now if you reload a page, if the user has already logged-in you will still have his info in he state
// Check for expired token
const currentTime = Date.now() / 1000;
if (decoded.exp < currentTime) {
// Logout User
store.dispatch(logoutUser());
// Redirect to login
window.location.href = "/login";
}
}
utils/setAuthToken.js
// What we will do here will prevent us from manually making sure of having the token inside each relevant request
// If we're logged-in, we can call this function and it will always attach that authorization header
// TODO: Need to make sure that the token is stored inside x-access-token
import axios from "axios";
const setAuthToken = token => {
console.log("setAuthToken is called");
if (token) {
// Apply to every request
axios.defaults.headers.common = {
// Authorization: token,
//TODO: Not sure about this
"x-access-token": token
};
console.log("token is: ");
console.log(token);
console.log("axios.defaults.headers.common: ");
console.log(axios.defaults.headers.common);
} else {
// Delete the Auth header
axios.defaults.headers.common = {
//Authorization: token,
"x-access-token": token
};
}
};
export default setAuthToken;
And this is the logging result of the setAuthToken:
setAuthToken.js:7 setAuthToken is called
setAuthToken.js:15 token is:
setAuthToken.js:16 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibm9tIjoiYXZlbXBhY2UiLCJlbWFpbCI6ImF2ZW1wYWNlQGF2ZW1wYWNlLmNvbSIsIm1vdF9kZV9wYXNzZSI6IlUyRnNkR1ZrWDEvRGdCN3JUUjB1YTJvc1BIcm1hRkswN3pjTGd5aSsxcE09IiwibGFzdF9sb2dpbiI6bnVsbCwicm9sZSI6InN1cGVyX3VzZXIiLCJjcmVhdGVkQXQiOiIyMDIwLTAyLTI4VDA5OjQwOjE4LjM3MFoiLCJ1cGRhdGVkQXQiOiIyMDIwLTAyLTI4VDA5OjQwOjE4LjM3MFoiLCJpYXQiOjE1ODI5MDg0NjAsImV4cCI6MTU4MjkxMjA2MH0.8Btk4f0Bdw-pM2qGEbk0s5V-u3jBugIHYDKH8aoDzW8
setAuthToken.js:17 axios.defaults.headers.common:
setAuthToken.js:18 {x-access-token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwib…A2MH0.8Btk4f0Bdw-pM2qGEbk0s5V-u3jBugIHYDKH8aoDzW8"}
It seems to be working. However, as I said, in the backend when I use getAllAdmins that uses the new implementation of the axios url, the token is undefined
in the backend. But, when I use getAllAdmins2 that uses a direct implementation of the axios url, the code is well received in the backend and everything works fine.
Your issue is likely due to the fact that the axios instance in conf/api.js
is created before you set the token in axios.defaults
so your instance will be unaffected. I.e. your order is:
Since you essentially have a singleton axios instance, you can instead set it's defaults in place of the global defaults when the token is loaded, i.e.,
Before:
// This is setting the defaults used when creating instance and the global axios is used
axios.defaults.headers.common = {
...
After:
import API from "../conf/api";
...
// This will set the the defaults of your singleton instance
API.defaults.headers.common = {
...
The above should fix your issue with your current setup but an alternate option is to go back to using the global axios
(e.g. axios.get
) and instead set the base URL on it's defaults, i.e.:
// During app init:
axios.defaults.baseURL = 'http://your.base.url';