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

使用Mocha、Chai、SuperTest测试XSRF-TOKEN无效响应问题

问题分析与修复方案

你的测试代码存在两个核心问题,导致CSRF Token验证失败:

  • 两次请求使用独立的request(app)实例,Cookie无法在会话间共享,后端CSRF中间件需要验证Cookie与请求头中的Token是否匹配,而第二次请求未携带正确的Cookie。
  • 请求头设置错误,多数CSRF中间件(如Express的csurf)要求的是X-XSRF-TOKEN头,而非XSRF-TOKEN,且手动往Cookie中塞入XSRF-TOKEN属于多余操作。

修复步骤

  1. 复用SuperTest Agent实例:使用request.agent(app)创建持久化会话,自动管理Cookie,模拟浏览器的会话行为。
  2. 修正CSRF请求头:将请求头改为X-XSRF-TOKEN,无需手动设置Cookie,Agent会自动携带第一次请求获取的Cookie。
  3. 优化测试结构:用before钩子提前获取CSRF Token,确保登录测试执行时Token已准备就绪。

修改后的完整代码

const app = require('../../../app.js');
const expect = require('chai').expect;
const request = require('supertest');

// 创建持久化Agent实例,自动维护会话Cookie
const agent = request.agent(app);
let csrfToken;

describe('用户登录流程测试', () => {
  // 所有测试执行前先获取CSRF Token
  before((done) => {
    agent.get('/api/csrf-token')
      .expect(200)
      .then((res) => {
        csrfToken = res.body.csrfToken;
        expect(res.body).to.have.property('csrfToken');
        done();
      })
      .catch(done);
  });

  it('使用超级管理员凭证登录', (done) => {
    agent.post('/api/users/login')
      // 设置符合规范的CSRF请求头
      .set('X-XSRF-TOKEN', csrfToken)
      .send({ email: 'super@abc.com', password: 'abc' })
      .then((res) => {
        const body = res.body;
        console.log(body);
        // 修正断言逻辑:message是字符串,直接判断内容
        expect(body.message).to.include('Auth Successful');
        expect(body).to.have.property('token');
        done();
      })
      .catch(done);
  });
});

关键改动说明

  • 用request.agent(app)替代单次request(app),保证Cookie在整个会话中自动共享。
  • 移除手动设置Cookie的代码,Agent会自动携带第一次请求返回的Cookie。
  • 将请求头改为X-XSRF-TOKEN,匹配大多数CSRF中间件的验证要求。
  • 修正断言逻辑:原代码中expect(body.message).to.contain.property('Auth Successful')错误,因为message是字符串而非对象,改为to.include直接判断字符串内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:55:28