繁体   English   中英

Django CSRF保护问题

[英]Django CSRF Protection Issue

我刚刚开始第一次使用 Django 构建 API,但在尝试使用 Postman 测试端点时遇到了问题。当我向端点 http://localhost:8000/arithmetic/ 发送 POST 请求时包含以下 JSON:

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

我收到以下回复:

<!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
            <a href="https://docs.djangoproject.com/en/4.1/ref/csrf/">Django’s
                CSRF mechanism</a> 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 <a
                    href="https://docs.djangoproject.com/en/dev/topics/templates/#django.template.backends.base.Template.render"><code>render</code></a>
                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>

我不确定如何解决此问题以便我可以测试我的端点。

到目前为止,这是我的代码:

在算术应用程序中:

意见.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'
        })

网址.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 前端,但我想在尝试将其连接到前端之前自行测试端点以确保其正常工作。

任何帮助或指导将不胜感激。

解决此问题的最快方法是使用 Django 的csrf_exempt function为您的视图禁用 CSRF 保护

from django.views.decorators.csrf import csrf_exempt

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

您也可以在视图中使用装饰器:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
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'
        })

您还可以从配置文件中完全删除中间件,这将禁用所有端点的 CSRF 保护。 从配置文件中,删除此行:

django.middleware.csrf.CsrfViewMiddleware

注意:在大多数情况下不建议这样做,因为它会使您的 API 容易受到 CSRF 攻击。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM