I have a react/redux application that fetches a token from an api server. After the user authenticates I'd like to make all axios requests have that token as an Authorization header without having to manually attach it to every request in the action. I'm fairly new to react/redux and am not sure on the best approach and am not finding any quality hits on google.
Here is my redux setup:
// actions.js
import axios from 'axios';
export function loginUser(props) {
const url = `https://api.mydomain.com/login/`;
const { email, password } = props;
const request = axios.post(url, { email, password });
return {
type: LOGIN_USER,
payload: request
};
}
export function fetchPages() {
/* here is where I'd like the header to be attached automatically if the user
has logged in */
const request = axios.get(PAGES_URL);
return {
type: FETCH_PAGES,
payload: request
};
}
// reducers.js
const initialState = {
isAuthenticated: false,
token: null
};
export default (state = initialState, action) => {
switch(action.type) {
case LOGIN_USER:
// here is where I believe I should be attaching the header to all axios requests.
return {
token: action.payload.data.key,
isAuthenticated: true
};
case LOGOUT_USER:
// i would remove the header from all axios requests here.
return initialState;
default:
return state;
}
}
My token is stored in redux store under state.session.token
.
I'm a bit lost on how to proceed. I've tried making an axios instance in a file in my root directory and update/import that instead of from node_modules but it's not attaching the header when the state changes. Any feedback/ideas are much appreciated, thanks.
Similarly, we have a function to set or delete the token from calls like this:
We always clean the existing token at initialization, then establish the received one.
Sometimes you get a case where some of the requests made with axios are pointed to endpoints that do not accept authorization headers. Thus, alternative way to set authorization header only on allowed domain is as in the example below. Place the following function in any file that gets executed each time React application runs such as in routes file.
The best solution to me is to create a client service that you'll instantiate with your token an use it to wrap
axios
.In this client, you can also retrieve the token from the localStorage / cookie, as you want.
From the documentation of
axios
you can see there is a mechanism available which allows you to set default header which will be sent with every request you make.So in your case:
If you want, you can create a self-executable function which will set authorization header itself when the token is present in the store.
Now you no longer need to attach token manually to every request. You can place the above function in the file which is guaranteed to be executed every time (e.g: File which contains the routes).
Hope it helps :)
If you use "axios": "^0.17.1" version you can do like this:
Create instance of axios:
Then for any request the token will be select from localStorage and will be added to the request headers.
I'm using the same instance all over the app with this code:
Good luck.
If you want to call other api routes in the future and keep your token in the store then try using redux middleware.
The middleware could listen for the an api action and dispatch api requests through axios accordingly.
Here is a very basic example:
actions/api.js
middleware/api.js