Python @csrf_exempt 不适用于基于通用视图的类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27315592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
@csrf_exempt does not work on generic view based class
提问by castiel
class ChromeLoginView(View):
def get(self, request):
return JsonResponse({'status': request.user.is_authenticated()})
@method_decorator(csrf_exempt)
def post(self, request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return JsonResponse({'status': True})
return JsonResponse({'status': False})
I am expecting that the post does stopped by csrf, but it return 403 error.
我期待该帖子确实被 csrf 停止,但它返回 403 错误。
But if remove that decorator and do this in the URLConf
但是如果删除该装饰器并在 URLConf 中执行此操作
url(r'^chrome_login/', csrf_exempt(ChromeLoginView.as_view()), name='chrome_login'),
it will work.
它会起作用。
What happened here? didn't it supposed to work, because I guess that's what method_decorator do. I'm using python3.4 and django1.7.1
这里发生了什么?它不应该工作,因为我想这就是 method_decorator 所做的。我正在使用 python3.4 和 django1.7.1
Any advice would be great.
任何建议都会很棒。
采纳答案by knbk
You need to decorate the dispatch
method for csrf_exempt
to work. What it does is set an csrf_exempt
attribute on the view function itself to True
, and the middleware checks for this on the (outermost) view function. If only a few of the methods need to be decorated, you still need to use csrf_exempt
on the dispatch
method, but you can use csrf_protect
on e.g. put()
. If a GET
, HEAD
, OPTIONS
or TRACE
HTTP method is used it won't be checked whether you decorate it or not.
您需要装饰dispatch
方法csrf_exempt
才能工作。它所做的是将csrf_exempt
视图函数本身的一个属性设置为True
,中间件会在(最外面的)视图函数上检查这一点。如果只有几个方法需要修饰,你仍然需要csrf_exempt
在dispatch
方法上使用,但是你可以使用csrf_protect
在例如put()
。如果GET
,HEAD
,OPTIONS
或TRACE
使用HTTP方法不管你把装修与否也不会被选中。
class ChromeLoginView(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(ChromeLoginView, self).dispatch(request, *args, **kwargs)
def get(self, request):
return JsonResponse({'status': request.user.is_authenticated()})
def post(self, request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return JsonResponse({'status': True})
return JsonResponse({'status': False})
回答by Antoine Pinsard
As @knbk said, this is the dispatch()
method that must be decorated.
正如@knbk 所说,这是dispatch()
必须装饰的方法。
Since Django 1.9, you can use the method_decorator
directly on a class:
从 Django 1.9 开始,您可以method_decorator
直接在类上使用:
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class ChromeLoginView(View):
def get(self, request):
return JsonResponse({'status': request.user.is_authenticated()})
def post(self, request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return JsonResponse({'status': True})
return JsonResponse({'status': False})
This avoids overriding the dispatch()
method only to decorate it.
这避免了重写dispatch()
方法只是为了装饰它。
回答by vikas0713
If you are looking for Mixins to match your needs, then you can create a CSRFExemptMixin and extend that in your view no need of writing above statements in every view:
如果您正在寻找 Mixins 来满足您的需求,那么您可以创建一个 CSRFExemptMixin 并在您看来扩展它,而无需在每个视图中编写上述语句:
class CSRFExemptMixin(object):
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(CSRFExemptMixin, self).dispatch(*args, **kwargs)
After that Extend this in your view like this.
之后,像这样在您的视图中扩展它。
class ChromeLoginView(CSRFExemptMixin, View):
You can extend that in any view according to your requirement, That's reusability! :-)
您可以根据您的要求在任何视图中扩展它,这就是可重用性!:-)
Cheers!
干杯!
回答by Neil Hickman
Django bracesprovides a CsrfExemptMixin
for this.
Django 大括号CsrfExemptMixin
为此提供了一个。
from braces.views import CsrfExemptMixin
class ChromeLoginView(CsrfExemptMixin, View):
...