【问题标题】:Django and Axios Forbidden (CSRF token missing or incorrect.)Django 和 Axios 被禁止(CSRF 令牌丢失或不正确。)
【发布时间】:2021-10-24 06:08:39
【问题描述】:

我在尝试将 django 服务器连接到 axios 时遇到问题。这应该是一个简单的修复,但我被卡住了!

我从我的 django 服务器收到此错误:

[23/Aug/2021 19:25:36] "POST /subscription HTTP/1.1" 403 2519
Forbidden (CSRF token missing or incorrect.): /subscription

这是我正在使用的方法:

const newsletterSignUp = async function (email) {
  try {
    let res = await axios({
      method: "post",
      url: "http://127.0.0.1:8000/subscription",
      data: { email: email },
    });

    return res;
  } catch (err) {
    console.error(err);
    return err;
  }

我尝试添加自定义标题,但我认为名称中的破折号会导致问题,我不知道如何解决。

headers: { set-cookie: "csrftoken=ee95ec102d0d884ea95eb09cb421cdd8382aed79" }

我知道我的 Django 代码很好,因为它可以在浏览器中运行。我已附上以供参考。

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Email subscriptions</title>

    <!-- Bootstrap -->
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
    />
  </head>

  <body class="container py-4">
    <!--Email subscription Form -->
    <form method="post" action="{% url 'subscription' %}">
      {% csrf_token %}

      <div class="form-group">
        <label>Subscribe to get the latest Articles</label> <br />
        <input
          type="email"
          name="email"
          placeholder="Enter Email to Subscribe"
        />
        <button class="btn btn-info" type="submit">Submit</button>
      </div>
    </form>

    <!-- message if email is sent -->
    {% if messages %} {% for message in messages %}
    <div class="my-5 alert alert-success">
      <h5 class="m-0">{{ message }}</h5>
    </div>
    {% endfor %} {% endif %}
  </body>
</html>

urls.py

urlpatterns = [
    path('', include(router.urls)),
     path("subscription", views.subscription, name="subscription"),
]

views.py

from django.shortcuts import render

# Create your views here.
from rest_framework import generics
from rest_framework import viewsets
from django.http import HttpResponse

from rest_framework.response import Response

from django.contrib import messages
from django.conf import settings
from mailchimp_marketing import Client
from mailchimp_marketing.api_client import ApiClientError

# Mailchimp Settings
api_key = settings.MAILCHIMP_API_KEY
server = settings.MAILCHIMP_DATA_CENTER
list_id = settings.MAILCHIMP_EMAIL_LIST_ID


# Subscription Logic
def subscribe(email):
    """
     Contains code handling the communication to the mailchimp api
     to create a contact/member in an audience/list.
    """

    mailchimp = Client()
    mailchimp.set_config({
        "api_key": api_key,
        "server": server,
    })

    member_info = {
        "email_address": email,
        "status": "subscribed",
    }

    try:
        response = mailchimp.lists.add_list_member(list_id, member_info)
        print("response: {}".format(response))
    except ApiClientError as error:
        print("An exception occurred: {}".format(error.text))

        # Views here.

def subscription(request):
    if request.method == "POST":
        email = request.POST['email']
        subscribe(email)                    # function to access mailchimp
        messages.success(request, "Email received. thank You! ") # message

    return render(request, "index.html")

这是我在 settings.py

中的权限
REST_FRAMEWORK = {

    'DEFAULT_PERMISSION_CLASSES': [
       'rest_framework.permissions.AllowAny'
    ],

    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

任何直升机都能救我一命!

【问题讨论】:

    标签: javascript python django django-rest-framework axios


    【解决方案1】:

    在 django docs 中,它给出了在对 django 的请求中设置 csrf 令牌的示例。

    const request = new Request(
        /* URL */,
        {headers: {'X-CSRFToken': csrftoken}}
    );
    fetch(request, {
        method: 'POST',
        mode: 'same-origin'  // Do not send CSRF token to another domain.
    }).then(function(response) {
        // ...
    });
    

    如您所见,csrf 不是放在set-cookie 标头中。它放在名为X-CSRFToken 的标头中。

    【讨论】:

    • 这帮助很大!我还有另一个额外的问题,它希望我的数据在一个表单中,但我也解决了这个问题。
    猜你喜欢
    • 2019-11-24
    • 2021-01-08
    • 2020-10-12
    • 2015-10-15
    • 2020-12-24
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    相关资源
    最近更新 更多