Django-禁止在同一模板(ajax和表单)中处理多个CSRF令牌(CSRF令牌丢失或不正确。)

时间:2018-09-02 09:32:53

标签: python jquery ajax django django-templates

我有一个模板,其中有一个提交电子邮件地址的表单,并且我试图做一个复选框,以便用户可以选择是否接收电子邮件通知。

{% extends "base_generic.html" %}

{% block content %}
<h1>{{ user.username }}</h1>

<p> Email comfirmed? {{ user.profile.email_confirmed }}</p>

{% if user.profile.email_confirmed %}
  <p>Email confimed as {{ user.email }}</p>
{% else %}
<form method="post">
    {% csrf_token %}
    {% for field in form %}
      <p>
        {{ field.label_tag }}<br>
        {{ field }}
        {% if field.help_text %}
          <small style="color: grey">{{ field.help_text }}</small>
        {% endif %}
        {% for error in field.errors %}
          <p style="color: red">{{ error }}</p>
        {% endfor %}
      </p>
    {% endfor %}
    <button type="submit">Authentificate</button>
  </form>
{% endif %}
{% if posts %}
<p>Your posts: </p>
<ul>
      <li> {{ posts.author }} {{ posts.pub_date }}
          {% if post.last_edited != null %}
            Last edited: {{ post.last_edited }}
          {% endif %}
              <br>  
      <a href="{% url 'fortykwords:detail' posts.id %}">{{ posts.title }}</a></li>
      {% for tag in posts.tags.all %}
          <a href="{% url 'fortykwords:tag' tag.name %}">{{ tag.name }}</a>
      {% endfor %}

{% endif %}
</ul>
{% else %}
  <p>No posts are available.</p>
{% endif %}

<input type="checkbox" name="checkbox" id="{{request.user.id}}">Send me an email notifications when I receive a message.<br>


    <script type="text/javascript">
    window.CSRF_TOKEN = "{{ csrf_token }}";
      $(document).ready(function(){
          $("input:checkbox").change(function() { 
              if($(this).is(":checked")) { 
                  $.ajax({
                      url: "/permissions/",
                      type: 'POST',
                      data: { strID:$(this).attr("id"), strState:"1" },
                      csrfmiddlewaretoken: jQuery("[name=csrfmiddlewaretoken]").val(),
                  }
                );
              } else {
                  $.ajax({
                      url: "/permissions/",
                      type: 'POST',
                      data: { strID:$(this).attr("id"), strState:"0" },
                      csrfmiddlewaretoken: jQuery("[name=csrfmiddlewaretoken]").val(),
                  });
              }
          }); 
      });
  </script>
{% endblock %}

问题是,当我单击复选框时,它给我以下错误:

[02/Sep/2018 09:22:54] "POST /permissions/ HTTP/1.1" 403 2513
Forbidden (CSRF token missing or incorrect.): /permissions/

我知道这与CSRF令牌有关,但是我尝试了许多变体,但我不知道它可能是什么。我怀疑是因为我在表单中使用了一个令牌,而在AJAX请求中使用了另一个令牌。我应该更改什么以使CSRF令牌成功提交?

1 个答案:

答案 0 :(得分:0)

AJAX docs中,没有看到任何设置选项csrfmiddlewaretoken

您需要在数据或设置标头X-CSRFToken中传递令牌。

解决方案

$.ajax({
  url: "/permissions/",
  type: 'POST',
  data: {
    strID: $(this).attr("id"),
    strState: "0",
    csrfmiddlewaretoken: jQuery("[name=csrfmiddlewaretoken]").val()
  },
  // or you can set the header
  // headers: {
  //   "X-CSRFToken": jQuery("[name=csrfmiddlewaretoken]").val()
  // }
})