2014-12-05 27 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不能在基於通用視圖的類上工作

但是,如果去除裝飾和做這個URL配置

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

它會奏效。

這裏發生了什麼事?它不應該工作,因爲我猜這就是method_decorator所做的。 我使用python3.4和django1.7.1

任何意見都會很好。

+0

你應該看看django_braces ... – rnevius 2014-12-05 13:28:57

+0

@rnevius非常感謝,以前從來不知道這個mixin lib。 – castiel 2014-12-05 14:31:20

+1

超級棒!特別是因爲您可以簡單地將[CsrfExemptMixin](https://django-braces.readthedocs.org/en/v1.4.0/form.html#csrfexemptmixin)添加到您的視圖以使其工作。這幾乎就像是作弊... – rnevius 2014-12-05 14:37:29

回答

45

你需要修飾dispatch方法csrf_exempt才能正常工作。它所做的是將視圖函數本身的csrf_exempt屬性設置爲True,並且中間件在(最外層)視圖函數中檢查此屬性。如果只需要對少數幾種方法進行修飾,您仍然需要在dispatch方法上使用csrf_exempt,但您可以在例如csrf_protect上使用csrf_protectput()。如果使用GETHEAD,OPTIONSTRACE 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()方法僅適用於裝飾。

相關問題