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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 01:38:51  来源:igfitidea点击:

@csrf_exempt does not work on generic view based class

pythondjango

提问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 dispatchmethod for csrf_exemptto work. What it does is set an csrf_exemptattribute 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_exempton the dispatchmethod, but you can use csrf_protecton e.g. put(). If a GET, HEAD, OPTIONSor TRACEHTTP method is used it won't be checked whether you decorate it or not.

您需要装饰dispatch方法csrf_exempt才能工作。它所做的是将csrf_exempt视图函数本身的一个属性设置为True,中间件会在(最外面的)视图函数上检查这一点。如果只有几个方法需要修饰,你仍然需要csrf_exemptdispatch方法上使用,但是你可以使用csrf_protect在例如put()。如果GETHEADOPTIONSTRACE使用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_decoratordirectly 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 CsrfExemptMixinfor this.

Django 大括号CsrfExemptMixin为此提供了一个。

from braces.views import CsrfExemptMixin

class ChromeLoginView(CsrfExemptMixin, View):
    ...