Django REST Framework 只允许超级用户访问 api web 视图

Posted

技术标签:

【中文标题】Django REST Framework 只允许超级用户访问 api web 视图【英文标题】:Django REST Framework allow only superusers to access api web view 【发布时间】:2018-10-24 06:59:51 【问题描述】:

我正在使用Django 2.0Django RESET Framework 为我的应用程序编写REST API

我已经配置了以下认证方式

REST_FRAMEWORK = 
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),

截至目前,它允许所有经过身份验证的用户访问web api视图。

我想要的是让少数用户(可能是超级管理员用户)能够通过登录从会话身份验证或网络浏览器访问 API。

编辑 2:contacts/views.py

class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (IsAuthenticated,)

    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user)

【问题讨论】:

你能添加你的联系人 API 视图吗? 更新了有问题的代码 您确定浏览器请求使用的是经过身份验证的用户? 知道了,我的配置有点错误。但是如何只限制超级管理员用户访问网络呢? 您必须创建一个自定义中间件或将其构建到您的视图中。没有任何理由根据有效用户访问系统的方式来限制他们使用相同的功能。 【参考方案1】:

因此,您可以利用 permission_classes 来执行此操作。 DRF 的Request 对象会记住在名为_authenticator 的属性中使用的身份验证方法。你可以用这个;并使用 permission_classes 来确定这对 (user,authenticator) 是否有权限

class AdminAuthenticationPermission(permissions.BasePermission):
    ADMIN_ONLY_AUTH_CLASSES = [rest_framework.authentication.BasicAuthentication, rest_framework.authentication.SessionAuthentication]

    def has_permission(self, request, view):
        user = request.user
        if user and user.is_authenticated():
            return user.is_superuser or \
                not any(isinstance(request._authenticator, x) for x in self.ADMIN_ONLY_AUTH_CLASSES) 
        return False

class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)

未经测试:但应该可以工作

【讨论】:

很好用。只需要很少的修改。从is_authenticated() 中删除()。休息很好 很高兴听到!我认为这是 Django 1.10 的一个变化;我比较习惯 1.9 旧习惯 docs.djangoproject.com/en/2.0/releases/1.10/… 是的,我在 1.10 之前的版本中使用过同样的东西。但它会在2.0 上返回TypeError: 'bool' object is not callable 我建议您更新您的问题以反映真正的潜在问题和相应的答案,以便将来更好地参考。 user.is_authenticated() 的末尾删除() 以修复TypeError @AnujTBE【参考方案2】:

对于 Django 2(在 views.py 中添加)

from rest_framework.permissions import IsAdminUser

class IsSuperUser(IsAdminUser):
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_superuser)

class ListSmth(ListCreateAPIView):
    permission_classes = (IsSuperUser,)
    ... Your code...

【讨论】:

继承自rest_framework.permissions.BasePermission 比继承自rest_framework.permissions.IsAdminUser 更好【参考方案3】:

已经有一个名为 IsAdminUser 的内置类,将其指定为 permission_classes 属性的值

from rest_framework.permissions import  IsAdminUser
     class A:
       permission_classes = (IsAdminUser,)

这会检查值

reques.user.isStaff == True

【讨论】:

以上是关于Django REST Framework 只允许超级用户访问 api web 视图的主要内容,如果未能解决你的问题,请参考以下文章

使用 Django rest_framework_jwt,如何允许使用准时使用代码自动登录?

Django:rest framework之分页(Pagination)

Django rest framework 之 DictField、ListField、自定义字段

如何在 django-rest-framework 中为 API 使用 TokenAuthentication

如何仅使用 django 作为后端并使用 django-rest-framework 发布

Django REST Framework 创建自定义用户