我正在使用Pyres工作人员对表单中输入的数据进行一些处理 . 他们的处理是通过我的表单上的视图完成的,我向POST发出请求,其中包括要处理的数据和用户的CSRF中间件令牌 . 我的问题是,这显然是不够的,因为Django仍拒绝我的禁止403的请求 .
相关代码:
表单处理程序
def handler(request):
if(request.method == "POST"):
if(request.POST.__contains__("taskdata")):
#valid post of the form
taskdata = escape(request.POST.get("taskdata",""))
t = TaskData(data=taskdata, time_added=timezone.now(), token=request.POST.get("csrfmiddlewaretoken",""))
t.save()
r = ResQ(server="127.0.0.1:6379")
r.enqueue(TaskData, t.id)
return HttpResponse(t.id)
else:
#invalid post of the form
raise Http404
else:
raise Http404
Pyres工作者:
@staticmethod
def perform(taskData_id):
#Get the taskData from this id, test it for tasky stuff
task_data = TaskData.objects.get(pk=taskData_id)
post_data = [('id',task_data.id),('data',task_data.data), ('csrfmiddlewaretoken',task_data.token)] # a sequence of two element tuples
result = urllib2.urlopen('http://127.0.0.1:8000/tasks/nlp/process/', urllib.urlencode(post_data))
content = result.read()
return
查看被该职位发布:
def process(request):
if(request.method == "POST"):
return HttpResponse("HEY, it works!")
if(request.POST.__contains__("data") and request.POST.__contains__("id")):
#valid post to the form by the model
#taskdata = escape(request.POST.get("taskdata",""))
#data = get_times(taskdata)
return HttpResponse("Hey from process!")
#return HttpResponse(json.dumps(data))
else:
#invalid post of the form
raise Http404
else:
raise Http404
我基本上要做的是在表单提交时保存一些原始数据,以及它的CSRF令牌 . 然后,工作人员将该数据令牌发送到处理视图 .
不幸的是,发布令牌似乎还不够 .
有谁知道csrf保护实际上是什么样的,以及我如何使我的Pyres工作者合规?
(建议标签:pyres)
1 回答
我想我看到了问题 .
Django's CSRF protection works的方式是生成一个nonce,然后将cookie设置为nonce的值,并确保
csrfmiddlewaretoken
POST值与cookie的值匹配 . 理由是它使它成为一个无状态系统,它在没有任何持久会话数据的情况下工作 .问题是你在Pyres工作人员的工作中提出的请求......
...来自服务器,而不是客户端,因此它不会设置cookie .
假设
/tasks/nlp/process/
URL受到保护,只能由服务器访问,那么使用process()
视图exempt from CSRF checking可能是最简单的......否则你必须在
handler()
视图中手动获取cookie值,并将其传递给Pyres工作者作业 .Update
要确保
process()
方法只能由服务器调用,一种简单的方法是检查请求对象,如......虽然可能有一些内置装饰器或某些为你做这件事 .