Custom Cookie Jars for Axios in Node.js

By default, Axios does not store or forward cookies across HTTP requests in Node.js environments like a web browser does. To enable automatic cookie persistence, you can pair Axios with tough-cookie and axios-cookiejar-support. This guide explains how to install the necessary packages, configure a custom cookie jar, and automatically persist session cookies across sequential HTTP requests.

Browsers automatically manage incoming Set-Cookie response headers and include matching cookies in outgoing request headers. In Node.js, Axios operates without a browser context, treating each request as stateless unless cookie headers are manually parsed and attached. A custom cookie jar captures incoming cookies, stores them in memory (or persistent storage), and appends them to subsequent requests targeting matching domains and paths.

Installation

Install Axios along with axios-cookiejar-support and tough-cookie:

npm install axios axios-cookiejar-support tough-cookie

Basic Implementation

To enable automatic cookie handling, wrap your Axios instance using wrapper from axios-cookiejar-support and pass an instance of CookieJar from tough-cookie.

const axios = require('axios');
const { wrapper } = require('axios-cookiejar-support');
const { CookieJar } = require('tough-cookie');

// 1. Create a new CookieJar instance
const jar = new CookieJar();

// 2. Create an Axios instance wrapped with cookie jar support
const client = wrapper(
  axios.create({
    jar,
    withCredentials: true, // Allows cross-site Access-Control requests to include cookies
  })
);

async function run() {
  try {
    // First request: The server responds with Set-Cookie
    await client.get('https://httpbin.org/cookies/set?session_id=12345&user=john');

    // Second request: The client automatically includes the stored cookies
    const response = await client.get('https://httpbin.org/cookies');

    console.log('Stored cookies returned by server:', response.data.cookies);
    // Output: { session_id: '12345', user: 'john' }
  } catch (error) {
    console.error('Request failed:', error.message);
  }
}

run();

Inspecting and Manually Adding Cookies

You can interact directly with the CookieJar instance to view stored cookies or manually inject cookies before sending a request.

const url = 'https://example.com';

// Add a cookie string directly to the jar for a specific URL
await jar.setCookie('auth_token=xyz987; Domain=example.com; Path=/', url);

Retrieving Stored Cookies

// Get all cookies valid for a specific URL
const cookies = await jar.getCookies('https://example.com');
console.log(cookies);

// Or get all cookies as a single 'Cookie' header string
const cookieString = await jar.getCookieString('https://example.com');
console.log(cookieString); // e.g., "auth_token=xyz987"

Persisting Cookies to Disk

For long-term persistence across application restarts, serialize the jar to JSON or use a storage engine like tough-cookie-filestore2.

Serializing and Restoring JSON

const fs = require('fs');

// Save jar to file
async function saveJar(jar, filePath) {
  const data = JSON.stringify(jar.toJSON());
  fs.writeFileSync(filePath, data, 'utf-8');
}

// Restore jar from file
async function loadJar(filePath) {
  if (fs.existsSync(filePath)) {
    const rawData = fs.readFileSync(filePath, 'utf-8');
    return CookieJar.fromJSON(JSON.parse(rawData));
  }
  return new CookieJar();
}

Per-Request Jar Configuration

If you prefer not to attach a single cookie jar to an entire Axios instance, you can pass individual jars inside the request config:

const client = wrapper(axios.create());
const userSessionJar = new CookieJar();

await client.get('https://example.com/login', {
  jar: userSessionJar,
});