2017-04-05 25 views
0

我試圖定義一個裝飾來檢查用戶具有管理員某些特權引發異常:user_passes_test:如果用戶沒有通過

def admin_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None): 
    actual_decorator = user_passes_test(
     lambda u: u.is_staff and u.is_authenticated() and not Association.objects.filter(admins=u).exists(), 
     login_url=login_url, 
     redirect_field_name=redirect_field_name 
    ) 
    if function: 
     return actual_decorator(function) 
    return actual_decorator 

的目的是利用這個throught的意見。特別是,我使用它在基於類的觀點:

class MyCBV(CreateView): 
    @method_decorator(admin_required) 
    def dispatch(self, request, *args, **kwargs): 
     return super(MyCBV, self).dispatch(request, *args, **kwargs) 

的問題是,這種觀點是通過AJAX加載的,所以重定向不會發生。此外,即使用戶身份驗證失敗,視圖返回的HTTP狀態也會成功,因此客戶端(JS)無法判斷操作何時成功或失敗。

我通常無法理解裝飾器和Django身份驗證,所以我的問題是:如何在身份驗證裝飾函數失敗時引發異常(最好是PermissionDenied異常)?

回答

0

在Django 1.9+中,您可以使用UserPassesTestMixin而不是裝飾器,並將raise_exception設置爲True

由於您使用的是不安全且過時的Django 1.4,因此您將無法執行此操作。沒有選項可以使user_passes_test增加PermissionDenied而不是重定向。您可以嘗試檢測JavaScript中的重定向,或者查看user_passes_test源代碼並實現類似的功能,以返回所需的響應。

+0

有沒有什麼辦法可以設置不同的裝飾器來引發異常?正如我所提到的,我不擅長開發裝飾器,但是我覺得我可以做到這一點,只要我能理解一件事情:用戶如何傳遞給'user_passes_test'?這似乎有點神奇。如果我能弄清楚如何從裝飾器中獲取請求的用戶,我很樂意去。 – dabadaba

+0

您可以編寫自己的引發異常的修飾器。查看'user_passes_test'的[源代碼](https://github.com/django/django/blob/4202ed243710926c3f059d848304145bd6b89225/django/contrib/auth/decorators.py#L10)將是一個很好的開始。在裝飾器中創建的'_wrapped_view'將'request'作爲第一個參數。它可以使用'request.user'訪問用戶。 – Alasdair

相關問題