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

Django API测试时遭遇CSRF验证失败问题求助

解决Django API测试时的CSRF 403错误

问题场景

首次用Django开发API,通过Postman向http://localhost:8000/arithmetic/发送POST请求,请求JSON内容如下:

{
  "expression": "1 + 2 × 3"
}

收到403 Forbidden响应,核心错误提示:CSRF token from the 'X-Csrftoken' HTTP header has incorrect length

完整错误响应

<!DOCTYPE html>
<html lang="en">

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta name="robots" content="NONE,NOARCHIVE">
    <title>403 Forbidden</title>
    <style type="text/css">
        html * {
            padding: 0;
            margin: 0;
        }

        body * {
            padding: 10px 20px;
        }

        body * * {
            padding: 0;
        }

        body {
            font: small sans-serif;
            background: #eee;
            color: #000;
        }

        body>div {
            border-bottom: 1px solid #ddd;
        }

        h1 {
            font-weight: normal;
            margin-bottom: .4em;
        }

        h1 span {
            font-size: 60%;
            color: #666;
            font-weight: normal;
        }

        #info {
            background: #f6f6f6;
        }

        #info ul {
            margin: 0.5em 4em;
        }

        #info p,
        #summary p {
            padding-top: 10px;
        }

        #summary {
            background: #ffc;
        }

        #explanation {
            background: #eee;
            border-bottom: 0px none;
        }
    </style>
</head>

<body>
    <div id="summary">
        <h1>Forbidden <span>(403)</span></h1>
        <p>CSRF verification failed. Request aborted.</p>


    </div>

    <div id="info">
        <h2>Help</h2>

        <p>Reason given for failure:</p>
        <pre>
    CSRF token from the &#x27;X-Csrftoken&#x27; HTTP header has incorrect length.
    </pre>


        <p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when
            Django’s
                CSRF mechanism has not been used correctly. For POST forms, you need to
            ensure:</p>

        <ul>
            <li>Your browser is accepting cookies.</li>

            <li>The view function passes a <code>request</code> to the template’s <code>render</code>
                method.</li>

            <li>In the template, there is a <code>{% csrf_token
    %}</code> template tag inside each POST form that
                targets an internal URL.</li>

            <li>If you are not using <code>CsrfViewMiddleware</code>, then you must use
                <code>csrf_protect</code> on any views that use the <code>csrf_token</code>
                template tag, as well as those that accept the POST data.</li>

            <li>The form has a valid CSRF token. After logging in in another browser
                tab or hitting the back button after a login, you may need to reload the
                page with the form, because the token is rotated after a login.</li>
        </ul>

        <p>You’re seeing the help section of this page because you have <code>DEBUG =
  True</code> in your Django settings file. Change that to <code>False</code>,
            and only the initial error message will be displayed. </p>

        <p>You can customize this page using the CSRF_FAILURE_VIEW setting.</p>
    </div>

</body>

</html>

现有代码

算术应用的views.py

import json
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse

# Create your views here.


def parse_request(str):
    if '×' in str:
        str = str.replace('×', '*')

    if '÷' in str:
        str = str.replace('÷', '/')


def calculate(request):
    if request.method == 'POST':
        # parse the json object
        body = json.loads(request.body)

        expression = body['expression']

        return JsonResponse({
            'response': expression
        })
    else:
        return JsonResponse({
            'error': 'invalid request method'
        })

算术应用的urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.calculate)
]

主项目的urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('arithmetic/', include('arithmetic.urls'))
]

解决方案

你开发的是供React前端调用的API,Django默认的CSRF保护主要针对浏览器表单提交场景,API场景下不需要,可通过以下两种方式解决:

方式一:给视图添加csrf_exempt装饰器

直接修改算术应用的views.py,导入并使用csrf_exempt装饰器跳过CSRF验证:

import json
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt  # 新增导入

def parse_request(str):
    if '×' in str:
        str = str.replace('×', '*')

    if '÷' in str:
        str = str.replace('÷', '/')


@csrf_exempt  # 添加装饰器
def calculate(request):
    if request.method == 'POST':
        body = json.loads(request.body)
        expression = body['expression']
        return JsonResponse({'response': expression})
    else:
        return JsonResponse({'error': 'invalid request method'})

方式二:使用Django REST Framework的APIView(推荐)

如果后续要扩展API功能,建议使用更规范的Django REST Framework:

  1. 先安装依赖:pip install djangorestframework
  2. 在项目settings.py的INSTALLED_APPS中添加'rest_framework'
  3. 修改views.py:
from rest_framework.views import APIView
from rest_framework.response import Response
from django.http import JsonResponse

class CalculateView(APIView):
    def post(self, request):
        expression = request.data.get('expression')
        # 可调用parse_request处理表达式
        return Response({'response': expression})
    
    def get(self, request):
        return JsonResponse({'error': 'invalid request method'})
  1. 修改算术应用的urls.py:
from django.urls import path
from . import views

urlpatterns = [
    path('', views.CalculateView.as_view())
]

测试说明

修改代码后重启Django服务,再用Postman发送POST请求即可正常访问。后续对接React前端时,直接发送JSON请求即可,无需处理CSRF token。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 23:40:19