Django - 在同一个模板(ajax 和表单)中处理多个 CSRF 令牌禁止(CSRF 令牌丢失或不正确。)
Posted
技术标签:
【中文标题】Django - 在同一个模板(ajax 和表单)中处理多个 CSRF 令牌禁止(CSRF 令牌丢失或不正确。)【英文标题】:Django - dealing with multiple CSRF tokens in the same template (ajax and form) Forbidden (CSRF token missing or incorrect.) 【发布时间】:2019-02-07 16:19:00 【问题描述】:我有这个模板,其中有一个用于提交电子邮件地址的表单,我正在尝试制作一个复选框,以便用户可以选择是否接收电子邮件通知。
% 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 令牌?
【问题讨论】:
可能是因为你的 标签不在表单中? 糟糕!但是我改成<form> <input type="checkbox" name="checkbox" id="request.user.id">Send me an email notifications when I receive a message.<br> </form>
还是不行。
也许这与您的问题有关? ***.com/questions/5100539/…
我不确定您的 Ajax 为何试图再次从输入中获取令牌。你已经有了它,在window.CSRF_TOKEN
;你应该使用它..
您需要在您的 ajax 请求中添加一个标头变量,名为:'X-CSRFToken'
,这样您的标头将包含 'X-CSRFToken': PUT_YOUR_CSRF_TOKEN_HERE
【参考方案1】:
在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()
//
)
【讨论】:
以上是关于Django - 在同一个模板(ajax 和表单)中处理多个 CSRF 令牌禁止(CSRF 令牌丢失或不正确。)的主要内容,如果未能解决你的问题,请参考以下文章