0

I'm having an issue with doubleCsrf in my Express.js backend, and I keep getting the following error on every request:

ForbiddenError: invalid csrf token
    at doubleCsrf (file:///Users/admin/Documents/backend/node_modules/csrf-csrf/lib/esm/index.js:13:35)
    at file:///Users/admin/Documents/backend/routes/auth/csrfMiddleware.js:10:5
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async loadESM (node:internal/process/esm_loader:28:7)
    at async handleMainPromise (node:internal/modules/run_main:113:12) {
  code: 'EBADCSRFTOKEN

Backend:

Here is my middleware setup in csrfMiddleware.js:

import { doubleCsrf } from "csrf-csrf";
import dotenv from 'dotenv';

dotenv.config();

const {
    doubleCsrfProtection,
    generateToken,
    invalidCsrfTokenError
} = doubleCsrf({
    getSecret: () => process.env.VITE_CSRF_SECRET,
    cookieName: "XSRF-TOKEN",
    cookieOptions: {
        httpOnly: false,
        secure: false,
        sameSite: "Lax",
        path: "/",
        partitioned: true,
    },
    ignoredMethods: ["GET", "HEAD", "OPTIONS"], 
    getTokenFromRequest: (req) => {
        console.log("CSRF-token from request headers:", req.headers["x-csrf-token"]);
        console.log("CSRF-token from cookies:", req.cookies["XSRF-TOKEN"]);

        return req.cookies["XSRF-TOKEN"];
    },
});

export { doubleCsrfProtection, generateToken, invalidCsrfTokenError };

Then in** server.js,** I generate and store the CSRF token in a cookie:

app.get('/api/auth/csrf-token', (req, res) => {
    const csrfToken = generateToken(req, res);

    res.clearCookie("XSRF-TOKEN");
    res.cookie("XSRF-TOKEN", csrfToken, {
        httpOnly: false,
        secure: false,
        sameSite: "Lax",
        path: "/"
    });

    res.json({ csrfToken });
});

// 📌 **API routes**
app.use('/api', apiRouter);

// ✅ CSRF protection applied here
app.use(doubleCsrfProtection);

Frontend (Vue)

On the frontend, I'm fetching the CSRF token before making any API requests:

import axios from 'axios';

const baseURL = import.meta.env.VITE_API_BASE_URL;

const axiosInstance = axios.create({
  baseURL,
  withCredentials: true,
});


let isFetchingCsrfToken = false;

const fetchCsrfToken = async () => {
  if (isFetchingCsrfToken) return;
  isFetchingCsrfToken = true;

  try {
    const response = await axiosInstance.get('/auth/csrf-token');
    if (response.data.csrfToken) {
      document.cookie = `XSRF-TOKEN=${response.data.csrfToken}; path=/`;
      axiosInstance.defaults.headers.common['X-CSRF-Token'] = response.data.csrfToken;
      console.log('CSRF-token set:', response.data.csrfToken);
    }
  } catch (error) {
    console.error('Error fetching CSRF token:', error);
  } finally {
    isFetchingCsrfToken = false;
  }
};

fetchCsrfToken();

export default axiosInstance;

When I log document.cookie in the console tab, I can see the token correctly set. Also The backend logs show that the token is received in the request headers and cookies

What could be the issue?

1
  • I have the same problem. Does anyone have a solution? Commented Sep 21 at 12:03

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.