多个模板的 csrf 令牌问题
Posted
技术标签:
【中文标题】多个模板的 csrf 令牌问题【英文标题】:csrf token issue with multiple templates 【发布时间】:2014-12-29 10:03:38 【问题描述】:我有一个模板(index.html。它扩展了 base.html),其中包含一个带有 csrf_token 的表单,效果很好。我使用 JS/Ajax 将数据发送到我的视图。所以没问题。
问题是,如果我将表单复制/粘贴到另一个模板(例如:new.html,它也扩展了 base.html),我会得到:CSRF 令牌丢失或错误错误。 (控制台出现 HTTP 403 错误)
两个模板使用相同的 JS 函数。两个模板中的表单完全相同。
有什么建议吗?
这里的表单(index.html 和 new.html 相同):
<form method="post" action="." enctype="multipart/form-data">
% csrf_token %
<a href="#" class="heart pull-right" onclick="return Favorite(this)" data="foobar">
<i class="fa fa-heart-o"></i>
</a>
</form>
这里是 JS/Ajax 函数:
function Favorite(item)
song_id = item.getAttribute("data"),
$.ajax(
type : "POST",
datatype: "json",
url: "/fav/",
data:
'csrfmiddlewaretoken' : $('input[name=csrfmiddlewaretoken]').val(),
song_id : song_id
,
);
return false
顺便说一下,index.html 中的表单是在一个 div 中。在 new.html 中,表单位于表格中。不知道有没有帮助。
【问题讨论】:
显示new.html
只是一个sn-p,您正在使用该表单。还有JS
函数。
您需要更多信息吗?
先检查token是否通过?在您的 JS 函数 alert
或写入 console.log
的值 $('input[name=csrfmiddlewaretoken]').val()
例如alert($('input[name=csrfmiddlewaretoken]').val());
返回index.html模板中的token值。但它在 new.html 模板中返回“未定义”
@NabIlovich 很明显,您的 csrf 选择器是错误的!或者 new.html 中没有输入字段
【参考方案1】:
首先,如果您使用 ajax 发送请求,则根本不需要 <form>
。
其次,你也可以这样设置csrf_token
:
...
data:
csrfmiddlewaretoken: ' csrf_token ',
song_id : song_id
,
...
这对我总是有效的。
【讨论】:
我删除了表单并尝试了您的代码但没有结果:/。我仍然遇到 403 问题。 @NabIlovich 你用的是什么版本的 django? @NabIlovich 只需复制此文件,将其保存到单独的 js 文件中,然后将其导入您的 base.html 到顶部。 pastebin.com/u7vbfDMK Django 1.7 和 python 3.4 如果我理解你的脚本,它会从 cookie 中读取 csrf 令牌,对吗? (我是开发新手)。我添加了它,但没有结果。【参考方案2】:我终于成功了(基于 django doc 和 doniyor cmets)
function getCookie(name)
var cookieValue = null;
if (document.cookie && document.cookie != '')
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++)
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '='))
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
return cookieValue;
function Favorite(item)
song_id = item.getAttribute("data-mp3"),
csrftoken = getCookie('csrftoken');
$.ajax(
type : "POST",
datatype: "json",
url: "/fav/",
data:
song_id : song_id
,
headers:
'X-CSRFToken': csrftoken
);
return false;
【讨论】:
以上是关于多个模板的 csrf 令牌问题的主要内容,如果未能解决你的问题,请参考以下文章
无模板 Django + AJAX:Django 的 CSRF 令牌是不是在浏览会话过程中更新?
spring security 3.2.0 csrf 令牌在 freemarker 模板中不起作用