Django Rest Framework身份验证 - 如何实现自定义装饰器

时间:2014-06-30 14:35:37

标签: django django-views django-rest-framework

我正在尝试使用Rest Framework实现TokenAuthentication,但似乎我无法将自己的自定义装饰器添加到我的ViewSets,因为它们在身份验证之前进行了评估。考虑一下:

from django.utils.decorators import method_decorator
from django.http.response import HttpResponseForbidden

def require_staff(View):
    def staffOnly(function):
        def wrap(request, *args, **kwargs):
            if request.user.is_active and request.user.is_staff:
                return function(request, *args, **kwargs)
            else:
                return HttpResponseForbidden()
        return wrap

    View.dispatch = method_decorator(staffOnly)(View.dispatch)
    return View

当我尝试实现它时,似乎装饰器代码首先触发,因此永远不会运行身份验证。

@require_staff
class CustomerViewSet(ModelViewSet):
    model = Customer

    filter_class = CustomerFilter
    filter_backends = (DjangoFilterBackend,)

由于永远不会设置 request.user ,因此引入装饰器会破坏身份验证。

我认为问题在于身份验证正在出现rest_frameworks dispatch()函数,如果在游戏后期进行身份验证,我不清楚如何添加其他(比如说)自定义安全性。

我在这里遗漏了什么,或者实现这种自定义的正确方法是什么?

有人建议使用权限代替。我认为它们意味着自定义DRF权限,对吧?

1 个答案:

答案 0 :(得分:1)

您需要知道的一切是DRF权限:http://www.django-rest-framework.org/api-guide/permissions

DRF提供与您类似的内置权限,称为IsAdminUser

  

IsAdminUser权限类将拒绝任何用户的权限,   除非user.is_staffTrue,否则将允许此权限。

     

此权限适用于您希望只能访问您的API   到可信管理员的子集。

在基于类的视图中使用此权限:

class ExampleView(APIView): permission_classes = (IsAdminUser,)

现在您有两个选项可以对user.is_active进行额外检查。

第一个是覆盖IsAdminUser权限,如下所示:

from rest_framework import permissions

class IsActiveAndAdminUser(permissions.IsAdminUser):
"""Only allow a user who is Admin and Active to view this endpoint. """
    def has_permission(self, request, view):
        is_admin = super(IsAdminAndActiveUser, self).has_permission(request, view)
        return request.user.is_active and is_admin

第二种方法是创建IsActiveUser权限,并在您的视图中对其进行链接。

IsActiveUser许可:

from rest_framework import permissions

class IsActiveUser(permissions.BasePermission):
""" Only Active Users have permission """
    def has_permission(self, request, view):
        return request.user.is_active

基于班级视图中的新权限列表:

class ExampleView(APIView): permission_classes = (IsActiveUser, IsAdminUser,)