Last active
September 13, 2024 00:50
-
-
Save nzvtrk/ebf494441e36200312faf82ce89de9f2 to your computer and use it in GitHub Desktop.
Axios create/recreate cookie session in node.js enviroment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Basic example of saving cookie using axios in node.js and session's recreation after expiration. | |
* We have to getting/saving cookie manually because WithCredential axios param use XHR and doesn't work in node.js | |
* Also, this example 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"]; // getting cookie from request | |
axiosInstance.defaults.headers.Cookie = cookie; // attaching cookie to axiosInstance for future requests | |
return cookie; // return Promise<cookie> because 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 = []; | |
}; | |
// registering axios interceptor which handle response's errors | |
axiosInstance.interceptors.response.use(null, error => { | |
console.error(error.message); //logging here | |
const { response = {}, config: sourceConfig } = error; | |
// checking 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 session context %s request to %s", sourceConfig.method, sourceConfig.url); | |
sourceConfig.headers.Cookie = cookie; // setting cookie to header | |
resolve(axios(sourceConfig)); // and resolve promise with axios request by old config with cookie | |
// we resolve exactly axios request - NOT axiosInstance's request because it could call recursion | |
}); | |
}); | |
return retryRequest; | |
} else { | |
// if error is not related with Unauthorized we just reject promise | |
return Promise.reject(error); | |
} | |
}); |
Have been stuck for 3h and your code works like a charm, thank you so much
It works! Thank you so much.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@nzvtrk ah ok, thanks 👍