删除隐藏字段后Django中的CSRF错误 [英] CSRF error in Django after removal of hidden fields
问题描述
我有一些 StackOverflow的好建议关于如何使用JavaScript删除所有隐藏的字段。
提交表单将用户发送到 / submit
,调用 submit_form
view。在我的views.py文件中,我定义了我的索引页面(使用表单),并且接收提交的页面(我的 / index
页面为我打印错误,但是不应该影响任何东西):
def index(request,error_message =''):
t = get_template index.html')
html = t.render(Context({'ERROR_MESSAGE':error_message}))
return HttpResponse(html)
def submit_form(request):
#从请求中获取POST数据并执行某些操作
pass
通过将代码更改为:
从django.contrib.csrf.middleware导入csrf_exempt $ b $已经能够抑制错误b
@csrf_exempt
def submit_form(request):
#从请求中获取POST数据并执行某些操作
pass
这实际上关闭了submit_form函数的CSRF。但是,我确信这不是理想的解决方案(现在我没有以我的形式检查伪造)。
我尝试了更复杂的修复, p>
-
添加此代码立即按照jQuery代码(将删除隐藏的字段提交)
init:function(){
var ac = this
#从StackOverflow中删除隐藏的
#来自POST提交的字段
jQuery(document).ready(function($){
$(form)。submit(function(){
$(this) find(:hidden)。remove();
});
#AJAX在此插入的CSRF代码
#...
}
- 在表单声明后立即添加{%csrf_token%}我也尝试过将代码添加到我的`index`视图,将`csrf_token`发送到`index`;这使得令牌可以在渲染的index.html源中查看(我收集的是一个坏主意)。
我看过几个问问这样的事情(和Django书中的引用),但还没有看到一个简单明了的答案。例如 - 即使我要容忍我发布我的 csrf_token
(我仍然知道这是一个坏主意),我是否应该在我的索引页面(然后它将提交表单将具有令牌),或者是否应该在我的 submit_form
代码中执行某些操作。 Django代码簿(上面链接)使用 my_view
作为呈现令牌的视图函数;这个名字不是很有帮助!
有没有人有一个小例子,CSRF工作(用javascript修改表单)?我真的认为这对我来说和StackOverflow上的很多其他人都是有用的,理想的情况是尽可能的简单(两个视图:一个传递表单,另一个打印其内容)。
非常感谢您的帮助。
更新: 我仍然收到此错误,即使我指定 csrfmiddlewaretoken
被删除,当我*没有进行任何JavaScript处理时,我的表单是正常的,我已经证实只有我的
有一些方法,CSRF可以看到一些表单元素被删除?我找不到任何不同于我的 QueryDict
对象(那从表单发送数据使用POST)。
我真的很感激任何帮助!
问题是您删除隐藏的CSRF字段,解决方法是n ot删除此字段,您可能可以使用jQuery选择器使其忽略该字段:not(input [name = csrfmiddlewaretoken])。
Btw,Django没有发送到表单类的未知字段名称的问题,它会高兴地忽略它们,因此删除隐藏字段的权衡非常小。
I got some good advice on StackOverflow about how to remove all hidden fields using JavaScript.
Submitting the form sends the user to /submit
, calling the submit_form
view. In my views.py file, I define my index page (with the form), and the page that receives the submission (my /index
page prints errors for me, but that shouldn't influence anything):
def index(request, error_message = ''):
t = get_template('index.html')
html = t.render(Context( { 'ERROR_MESSAGE': error_message } ))
return HttpResponse(html)
def submit_form(request):
# get the POST data out of request and do something
pass
I've been able to suppress the error by changing the code to:
from django.contrib.csrf.middleware import csrf_exempt
@csrf_exempt
def submit_form(request):
# get the POST data out of request and do something
pass
This essentially turns off CSRF for the submit_form function. However, I'm sure this is not the ideal fix (now I'm not checking for forgeries in my form).
I tried more sophisticated fixes, like
- Adding this code to immediately follow the jQuery code (which removes hidden fields from submission)
init:function(){
var ac=this
# advice from StackOverflow to remove hidden
# fields from POST submission
jQuery(document).ready(function($){
$("form").submit(function() {
$(this).find(":hidden").remove();
});
# AJAX CSRF code inserted here
#...
}
- Adding `{% csrf_token %}` immediately after my form declaration. I also tried adding code to my `index` view to send the `csrf_token` to `index`; that made the token viewable in the rendered index.html source (which I gathered was a bad idea).
I've seen several questions asking about things like this (and references in the Django book), but haven't seen a simple and clear answer. For instance-- even if I was going to tolerate publishing my csrf_token
(which, still I know is a bad idea), it is still unclear whether I should render that in my index page (and then it will submitted form will have the token) or whether I am supposed to do something in my submit_form
code. The Django code book (linked above) uses my_view
as the view function where the token is rendered; this name is not very helpful!
Does anyone have a small example with CSRF working (with javascript modifying the form)? I really think it would be useful (to me and to lots of other people on StackOverflow to see this. Ideally, it would be as simple as possible (two views: one delivers the form, the other prints its contents).
Thanks a lot for your help.
Update: I still get this error, even when I prefent the csrfmiddlewaretoken
from being removed. When I *do not do any JavaScript processing, my form is fine. And I've verified that only my
Is there some way that CSRF can see that some form elements are removed? I can't find anything different in my QueryDict
object (that sends the data from the form using POST).
I'd really appreciate any help!
The problem is that you remove the hidden CSRF-field and the solution is to not remove this field, you could probably do that with the jQuery selector to have it ignore that field with :not(input[name=csrfmiddlewaretoken]).
Btw, Django doesn't have a problem with unknown field names sent to the form-class, it will happily ignore them so the removal of the hidden fields tradeoff is very small.
这篇关于删除隐藏字段后Django中的CSRF错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!