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

如何在Next.js中为Django设置CSRF Cookie解决403错误

Next.js调用Django接口时CSRF 403错误的解决方法

问题描述

我是Next.js新手,正在给Django应用开发前端,当前调用Django接口的route.js代码如下:

import { NextResponse  } from 'next/server';
import axios from 'axios';
//import { cookies } from 'next/headers';

export async function POST(req: Request) {
  const { imageData } = req.body;
  try {
    // Django backend
    const response = await axios.post(
      'http://localhost:8000/souci/capture/', 
      { imageData }
    );
    return NextResponse.json({response});
  } catch (error) {
    console.error('Error sending image data to Django:', error);
    return NextResponse.json({ success: false, error: 'Failed to send image data to Django' });
  }
}

export async function GET(req: Request) {
  // return
}

Django控制台抛出403错误:

WARNING:django.security.csrf:Forbidden (CSRF cookie not set.): /souci/capture/
[20/Feb/2024 04:55:44] "POST /souci/capture/ HTTP/1.1" 403 2870

我尝试过两种方法但未解决:

  • 设置axios默认值:
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"
  • 创建固定值cookie(不确定如何关联到POST请求):
cookies().set('csrftoken', 'souci', {
  maxAge: 60 * 60 * 24, // 一天(秒)
  httpOnly: true, // 禁止客户端访问
  sameSite: 'strict',
});

需要解决如何在POST函数中正确配置CSRF Token的问题。


解决方案

1. 从Django获取合法CSRF Token并携带请求

不能手动设置固定CSRF Token,必须从Django获取有效Token,再携带到POST请求中:

import { NextResponse } from 'next/server';
import axios from 'axios';
import { cookies } from 'next/headers';

export async function POST(req: Request) {
  // 注意:必须await解析请求体
  const { imageData } = await req.json();
  try {
    // 第一步:请求Django的CSRF端点获取Token
    const csrfRes = await axios.get('http://localhost:8000/csrf/', {
      withCredentials: true, // 必须开启,才能接收并保存Django的CSRF Cookie
    });

    // 从响应头的Set-Cookie中提取csrftoken
    const csrfToken = csrfRes.headers['set-cookie']?.split('csrftoken=')[1]?.split(';')[0];

    // 第二步:携带CSRF Token发送POST请求
    const response = await axios.post(
      'http://localhost:8000/souci/capture/',
      { imageData },
      {
        headers: {
          'X-CSRFTOKEN': csrfToken, // 将Token放入请求头
        },
        withCredentials: true, // 保持会话Cookie传递
      }
    );

    return NextResponse.json(response.data);
  } catch (error) {
    console.error('Error sending image data to Django:', error);
    return NextResponse.json({ success: false, error: 'Failed to send image data to Django' });
  }
}

2. 配置Django允许跨域请求

因为本地开发时Next.js(通常3000端口)和Django(8000端口)属于跨域,需在Django中配置CORS:

  • 安装依赖:
pip install django-cors-headers
  • 修改settings.py:
INSTALLED_APPS = [
    # 原有应用
    'corsheaders',  # 添加这一行
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # 必须放在CommonMiddleware之前
    'django.middleware.common.CommonMiddleware',
    # 原有中间件
]

# 允许Next.js的本地地址
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
]

# 允许携带Cookie(关键,否则CSRF Token无法传递)
CORS_ALLOW_CREDENTIALS = True

3. 关键注意点

  • 禁止手动设置固定CSRF Token:Django的CSRF Token是动态生成的,固定值会被判定为非法。
  • 必须开启withCredentials: true:axios请求中开启此选项才能在请求间传递Cookie。
  • 正确解析请求体:Next.js API路由中,req.body需要用await req.json()解析,直接解构会得到undefined。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 11:03:34