Sup*_*ero 7 django httpresponse csrf
我有以下代码
def ajax_login_request(request):
try:
request.POST[u'login']
dictionary = request.POST
except:
dictionary = request.GET
user = authenticate(username = dictionary[u'login'], password = dictionary[u'password'])
if user and user.is_active:
login(request, user)
result = True
else:
result = False
response = HttpResponse(json.dumps(result), mimetype = u'application/json')
return response
Run Code Online (Sandbox Code Playgroud)
这是通过ajax调用的.我是一个菜鸟,这是一本书的例子.不幸的是,我正在使用的Django版本会引发CSRF错误.我已经完成了其他CSRF位,但我不知道如何将HttpResponse位更改为渲染调用.我不想使用CSRF_exempt,因为我不知道什么时候合适.有人可以请给我上面的HttpResponse等效的渲染调用.
谢谢
小智 7
好的,我将重新起草这个答案,以便你了解我的来源.CSRF中间件的工作方式如下:
You make request -------> request hits csrf --(invalid/no token)--> render 403
middleware
|
(valid token)
|
\ /
Call view
|
\ /
middleware sets
csrf cookie
|
\ /
Response appears
Run Code Online (Sandbox Code Playgroud)
换句话说,如果您看到403 csrf页面,则从未调用过您的视图.您可以通过在视图中粘贴虚假打印语句并runserver在发出请求时观察输出来确认这一点.
要解决此问题,您需要禁用csrf(不好)或使用其中一种可用的ajax方法.如果在视图中传递了所需的标记,则实际将执行.
未调用视图的原因是为了防止伪造站点的操作实际发生 - 例如,如果在响应时拒绝模板,则用户已经登录.功能装饰器也会出现相同的行为.
至于设置cookie的中间件,它根本不会改变或依赖于渲染功能 - 这会Cookie: ...在响应中设置HTTP头.Django中的所有响应都是HttpResponse对象,直到它最终将它们转换为输出; render函数是助手,但这不是导致你的问题的原因.
编辑我会将您所拥有的内容转换为渲染调用.你可以这样做:
return render_to_response(`ajax_templates/login_response.html`,
{'loginresponse': json.dumps(result)})
Run Code Online (Sandbox Code Playgroud)
在哪里ajax_templates/login_response.html:
{% loginresponse %}
Run Code Online (Sandbox Code Playgroud)
而已.HttpResponse有一个主要的默认参数,它是要返回的字符串(字面意思是网页的html); 这就是你最初做的事情.render_to_response并且render是执行此操作的快捷方式:
render_to_response called ----> open template asked for --> substitute arguments
|
\ /
django instructs web server <--- return this from view <-- create HttpResponse
to send to client object
Run Code Online (Sandbox Code Playgroud)
要使原始代码有效,您需要获取一个RequestContext对象并将其与您的响应一起传递,如下所示:
from django.http import HttpResponse
from django.template import RequestContext, Template
def ajax_login_request(request):
# ...
# This bit of code adds the CSRF bits to your request.
c = RequestContext(request,{'result':json.dumps(result)})
t = Template("{{result}}") # A dummy template
response = HttpResponse(t.render(c), mimetype = u'application/json')
return response
Run Code Online (Sandbox Code Playgroud)
请阅读CSRF文档,因为如果您不了解CSRF在您的应用中"有线"的所有方式,您可能会遇到奇怪的错误.该页面还有一个javascript代码段,以确保在没有表单的情况下发送CSR请求时,如果您发送了CSR错误请求.
您也可以使用render_to_response()快捷方式,但是您需要加载一个实际模板(在您的情况下,您不需要模板,因此在我的示例中为"虚拟"模板).