- 
      
- 
        Save nzvtrk/ebf494441e36200312faf82ce89de9f2 to your computer and use it in GitHub Desktop. 
| /* 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); | |
| } | |
| }); | 
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 a lot
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.
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
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 👍
Have been stuck for 3h and your code works like a charm, thank you so much
It works! Thank you so much.
Work like a charm ! Thanks a lot.