You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Node.js+Supertest/Supertest-Session复现Django/React应用Python登录脚本时缺失CSRF Cookie的问题

Troubleshooting Missing CSRF Token in Supertest/Supertest-Session for Django/React App

I’ve run into similar headaches testing Django apps with Supertest, so let’s break down the most likely fixes for your issue:

  • Always trigger a GET request first to fetch the CSRF token
    Django doesn’t automatically send the csrftoken cookie in POST requests—you need to first hit a route that triggers the CSRF middleware, like your login page’s GET endpoint or Django’s built-in /csrf/ view (if enabled). Unlike Postman/Curl where you might manually handle this step first, Supertest doesn’t do this automatically by default.

Here’s a practical example of how to structure this flow with Supertest-Session:

const request = require('supertest');
const session = require('supertest-session')('http://localhost:8000'); // Replace with your Django app URL

test('successful login with CSRF token', async () => {
  // Step 1: Fetch the CSRF token via a GET request to the login page
  const getLoginPage = await session.get('/accounts/login/');
  // Parse the csrftoken from the Set-Cookie header
  const csrfToken = getLoginPage.headers['set-cookie']
    .find(cookie => cookie.startsWith('csrftoken='))
    .split(';')[0]
    .split('=')[1];

  // Step 2: Use the extracted token to send your login POST request
  const loginResponse = await session.post('/accounts/login/')
    .set('X-CSRFToken', csrfToken) // Django expects this header for CSRF validation
    .send({
      username: 'your-test-user',
      password: 'your-test-password'
    });

  // Verify login success (adjust status code to match your app's behavior)
  expect(loginResponse.statusCode).toBe(302);
});
  • Match request headers to what Django expects
    Django’s CSRF middleware sometimes skips setting the cookie if the request headers don’t resemble a typical browser request. Supertest uses minimal default headers, so try adding common browser headers to your GET request:
const getLoginPage = await session.get('/accounts/login/')
  .set('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')
  .set('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36');
  • Check your Django settings for CSRF restrictions

    • If CSRF_COOKIE_SECURE is set to True in your test environment, Django will only send the CSRF cookie over HTTPS. For local testing, set this to False.
    • Ensure your test domain (usually localhost) is listed in CSRF_TRUSTED_ORIGINS if you’ve configured this setting—Django won’t send the CSRF cookie to untrusted origins.
  • Simplify cookie parsing with a library
    Instead of manually splitting the Set-Cookie header, use the cookie npm package to make parsing cleaner:

const cookie = require('cookie');

// ...
const cookies = cookie.parse(getLoginPage.headers['set-cookie'].join('; '));
const csrfToken = cookies.csrftoken;

The most common culprit here is forgetting that initial GET request—Django won’t send the CSRF cookie unless it detects a request that needs it (like a GET to a page with a form).

内容的提问来源于stack exchange,提问作者user2072187

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 13:18:14