Skip to content

Instantly share code, notes, and snippets.

@nzvtrk
Last active April 14, 2025 13:50
Show Gist options
  • Select an option

  • Save nzvtrk/ebf494441e36200312faf82ce89de9f2 to your computer and use it in GitHub Desktop.

Select an option

Save nzvtrk/ebf494441e36200312faf82ce89de9f2 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"][0]; // 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.map(sub => sub(cookie));
};
const addRequestToQueue = sub => {
requestQueue.push(sub);
};
// register axios interceptor which handle responses errors
axiosInstance.interceptors.response.use(null, error => {
console.error(error);
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);
requestQueue = []; // and clean queue
});
}
// 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'
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);
}
});
@notiles
Copy link

notiles commented Oct 14, 2020

Work like a charm ! Thanks a lot.

@YatseaLi
Copy link

Very nice work. Just a small thing:
line#64, it should be
console.log("Retry with new session context %s request to %s", sourceConfig.method, sourceConfig.url);
otherwise, it returns an error like "method undefined"

@YukiGibson
Copy link

Thanks a lot

@Splines
Copy link

Splines commented May 11, 2021

We have to getting/saving cookie manually because WithCredential axios param use XHR and doesn't work in node.js

Good to know, that's why axios didn't work for me at all. axiosInstance.defaults.headers.Cookie = cookie; did the trick for me.


Just a question: I've never seen a variable declared and initialized like this in JS: const [cookie] = resp.headers["set-cookie"];. This is just saving the first cookie, right? I've removed the square brackets in [cookie] to deal with multiple cookies at once.

@nzvtrk
Copy link
Author

nzvtrk commented May 11, 2021

Just a question: I've never seen a variable declared and initialized like this in JS: const [cookie] = resp.headers["set-cookie"];. This is just saving the first cookie, right? I've removed the square brackets in [cookie] to deal with multiple cookies at once.

Sure, its about array destructuring in JavaScript. resp.headers["set-cookie"] returns array with one elem ['yourCookieHere'].
And we can use const [cookie] = resp.headers["set-cookie"]; instead of const cookie = resp.headers["set-cookie"][0];

Very nice work. Just a small thing:
line#64, it should be
console.log("Retry with new session context %s request to %s", sourceConfig.method, sourceConfig.url);
otherwise, it returns an error like "method undefined"

Thanks! fixed

@Splines
Copy link

Splines commented May 21, 2021

Sure, its about array destructuring in JavaScript. resp.headers["set-cookie"] returns array with one elem ['yourCookieHere'].
And we can use const [cookie] = resp.headers["set-cookie"]; instead of const cookie = resp.headers["set-cookie"][0];

@nzvtrk ah ok, thanks 👍

@michael-he-nz
Copy link

Have been stuck for 3h and your code works like a charm, thank you so much

@mscw
Copy link

mscw commented Jan 11, 2022

It works! Thank you so much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment