Подтвердить что ты не робот

@csrf_exempt не работает в общем классе на основе представления

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})

Я ожидаю, что сообщение будет остановлено csrf, но оно вернет ошибку 403.

Но если удалить этот декоратор и сделать это в URLConf

url(r'^chrome_login/', csrf_exempt(ChromeLoginView.as_view()), name='chrome_login'),

он будет работать.

Что здесь произошло? разве он не должен работать, потому что я предполагаю, что делает method_decorator. Я использую python3.4 и django1.7.1

Любые советы были бы замечательными.

4b9b3361

Ответ 1

Вам нужно украсить метод 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})

Ответ 2

Как сказал @knbk, это метод dispatch(), который должен быть украшен.

Начиная с 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})

Это позволяет избежать переопределения метода dispatch() только для его украшения.

Ответ 3

Если вы ищете Mixins, чтобы соответствовать вашим потребностям, то вы можете создать CSRFExemptMixin и расширить его, по вашему мнению, не нужно писать вышеприведенные утверждения в каждом представлении:

class CSRFExemptMixin(object):
   @method_decorator(csrf_exempt)
   def dispatch(self, *args, **kwargs):
       return super(CSRFExemptMixin, self).dispatch(*args, **kwargs)

После этого расширьте это, по вашему мнению, следующим образом.

class ChromeLoginView(CSRFExemptMixin, View):

Вы можете расширить это в любом виде в соответствии с вашими требованиями, что возможность повторного использования! :-)

Ура!

Ответ 4

Django Braces предоставляет для этого CsrfExemptMixin.

from braces.views import CsrfExemptMixin

class ChromeLoginView(CsrfExemptMixin, View):
    ...