2014-12-05 3 views
27
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.@csrf_exempt не работает в классе общего класса

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

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

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

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

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

+0

Вы должны заглянуть в django_braces ... – rnevius

+0

@rnevius очень благодарен, никогда не знаю этот mixin lib для django раньше. – castiel

+1

Это супер круто! Тем более, что вы можете просто добавить к своему представлению [CsrfExemptMixin] (https://django-braces.readthedocs.org/en/v1.4.0/form.html#csrfexemptmixin), чтобы сделать эту работу. Это почти как обман ... – rnevius

ответ

45

Для работы необходимо выполнить 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}) 
34

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

С Django 1.9, you can use the method_decorator directly on a class:

@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() только украсить его.

Смежные вопросы