Skip to content

Instantly share code, notes, and snippets.

@CITGuru
Forked from nzvtrk/axiosInterceptor.js
Created May 7, 2020 13:55
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save CITGuru/61dd109adc2be5d3fd6274f15123fe0e to your computer and use it in GitHub Desktop.
Save CITGuru/61dd109adc2be5d3fd6274f15123fe0e to your computer and use it in GitHub Desktop.
Axios create/recreate cookie session in node.js enviroment
/* Basic example of save cookie using axios in node.js and recreate session if it expired.
* Get/save cookie manually cause WithCredential axios param use XHR and not work in node.js
* Supports parallel request and send only one create session request.
* */
const BASE_URL = "https://google.com";
// Init instance of axios which works with BASE_URL
const axiosInstance = axios.create({ baseURL: BASE_URL });
const createSession = async () => {
console.log("create session");
const authParams = {
username: "username",
password: "password"
};
const resp = await axios.post(BASE_URL, authParams);
const [cookie] = resp.headers["set-cookie"]; // get cookie from request
axiosInstance.defaults.headers.Cookie = cookie; // attach cookie to axiosInstance for future requests
return cookie; // return Promise<cookie> cause func is async
};
let isGetActiveSessionRequest = false;
let requestQueue = [];
const callRequestsFromQueue = cookie => {
requestQueue.forEach(sub => sub(cookie));
};
const addRequestToQueue = sub => {
requestQueue.push(sub);
};
const clearQueue = () => {
requestQueue = [];
};
// register axios interceptor which handle responses errors
axiosInstance.interceptors.response.use(null, error => {
console.error(error.message); //logging here
const { response = {}, config: sourceConfig } = error;
// check if request failed cause Unauthorized
if (response.status === 401) {
// if this request is first we set isGetActiveSessionRequest flag to true and run createSession
if (!isGetActiveSessionRequest) {
isGetActiveSessionRequest = true;
createSession().then(cookie => {
// when createSession resolve with cookie value we run all request from queue with new cookie
isGetActiveSessionRequest = false;
callRequestsFromQueue(cookie);
clearQueue(); // and clean queue
}).catch(e => {
isGetActiveSessionRequest = false; // Very important!
console.error('Create session error %s', e.message);
clearQueue();
});
}
// and while isGetActiveSessionRequest equal true we create and return new promise
const retryRequest = new Promise(resolve => {
// we push new function to queue
addRequestToQueue(cookie => {
// function takes one param 'cookie'
console.log("Retry with new cookie %s request to %s", method, url);
sourceConfig.headers.Cookie = cookie; // set cookie to header
resolve(axios(sourceConfig)); // and resolve promise with axios request by old config with cookie
// we resolve exactly axios request - NOT axiosInstance request cause it could call recursion
});
});
return retryRequest;
} else {
// if error is not related with Unauthorized we reject promise
return Promise.reject(error);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment