Staff-only permissions in Django Rest Framework

限于喜欢 提交于 2021-02-08 05:41:30

问题


I am trying to create Django Rest Framework ModelViewSets that are staff only. When i try to use the standard Django decorator @staff_member_required I get errors which make me believe the decorators won't work with Django Rest Framework.

So I am trying to write my own ModelViewSet mixin. It mostly works as I want, except for the update method which I can't make work.

So, two questions: is there a more elegant way to do this, and if not, what is wrong with my update method? I can't find any documentation on update, so I'm using my best guess as to how to super it, but it's not working.

Thanks!

John

Here is my class:

class StaffOnlyModelViewSet(viewsets.ModelViewSet):

def list(self, request):
    if self.request.user.is_staff:
        return super(StaffOnlyModelViewSet, self).list(request)
    else:
        content = {'Unauthorised': 'This API is private'}
        return Response(content, status=status.HTTP_401_UNAUTHORIZED)

def retrieve(self, request, pk=None):
    if self.request.user.is_staff:
        return super(StaffOnlyModelViewSet, self).retrieve(request, pk=None)
    else:
        content = {'Unauthorised': 'This API is private'}
        return Response(content, status=status.HTTP_401_UNAUTHORIZED)

def create(self, request):
    if self.request.user.is_staff:
        return super(StaffOnlyModelViewSet, self).create(request)
    else:
        content = {'Unauthorised': 'This API is private'}
        return Response(content, status=status.HTTP_401_UNAUTHORIZED)

def update(self, request, pk=None):
    if self.request.user.is_staff:
        return super(StaffOnlyModelViewSet, self).update(request, pk=None)
    else:
        content = {'Unauthorised': 'This API is private'}
        return Response(content, status=status.HTTP_401_UNAUTHORIZED)

def destroy(self, request, pk=None):
    if self.request.user.is_staff:
        return super(StaffOnlyModelViewSet, self).destroy(request, pk=None)
    else:
        content = {'Unauthorised': 'This API is private'}
        return Response(content, status=status.HTTP_401_UNAUTHORIZED)

回答1:


The more elegant way of achieving your goal is to use permissions. These can be declared globally, at the view level, or with a decorator

From the source:

class IsAdminUser(BasePermission):
    """
    Allows access only to admin users.
    """
    def has_permission(self, request, view):
        return request.user and request.user.is_staff

You can use this in your views.py (see the docs for other ways)

from rest_framework.permissions import IsAdminUser

class StaffOnlyModelViewSet(viewsets.ModelViewSet):
    permission_classes = (IsAdminUser,)

Some users are confused by permissions and authentication and the relation between them, so I will give you a quick primer.

Authentication defines the means for a user to prove their identity, and permissions define who has access to which resources. Whether or not the identity is proven during authentication, the user's request will be checked against permissions.

When combined together, you can control a users access. For example, if a user fails authentication but the permission class on a view is set to 'IsAuthenticatedOrReadOnly', they can still GET/LIST the resource. 'IsAdminUser' states that a user must have passed authentication and must also be staff to access this view. This is what you want in this case.



来源:https://stackoverflow.com/questions/31714198/staff-only-permissions-in-django-rest-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!