Django REST Framework-如何为非员工用户禁用可浏览的API(is_staff = False) [英] Django REST Framework - How to disable the browsable API for non staff users (is_staff=False)

查看:75
本文介绍了Django REST Framework-如何为非员工用户禁用可浏览的API(is_staff = False)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的情况下,我使用Django REST Framework(DRF)作为内部api。不适合普通用户使用。因此,我想对普通用户禁用它。

in my case I am using Django REST Framework (DRF) as internal api. it is not intended to be consumed by regular users. therefore I would like to disable it for regular users.

管理员( is_staff = True )应该能够访问并查看它:

an admin (is_staff=True) should be able to access it and see it:
https://restframework.herokuapp.com/

非工作人员用户( is_staff = False )应该只获取GET请求的JSON响应,例如:

https ://restframework.herokuapp.com/?format = json
< img src = https://i.stack.imgur.com/vca9P.png alt =在此处输入图片描述>
他应该不(!)请参阅可浏览的api。这适用于根视图和所有端点。

a non staff user (is_staff=False) should just get the JSON response of a GET request like:
https://restframework.herokuapp.com/?format=json he should not(!) see the browsable api. this applies for the root view and all endpoints.

要进行配置,我应用了以下内容:

to configure this, I applied the following:

# settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.SessionAuthentication'],
    'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated'],
}

我的端点如下(为了使示例简单,我只显示1):

my endpoints are the following (to keep the example simple I just show 1):

# api/urls.py
from django.urls import include, path

from rest_framework import routers

from . import views

app_name = 'api'

router = routers.DefaultRouter()  # browseable api
router.register('segments', views.SegmentViewSet)
# there are a lot more...

urlpatterns = [
    path('', include(router.urls)),
]

基于答案 https:/ /stackoverflow.com/a/58894198/420953 我的 settings.py 看起来像这样:

based on answer https://stackoverflow.com/a/58894198/420953 my settings.py looks like this:

# settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.SessionAuthentication'],
    'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated'],
    # enable JSON renderer by default
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
}

和我的 api /视图。 py

# api/views.py

from django_filters import rest_framework as drf_filters
from rest_framework import filters, renderers, viewsets

from . import serializers
from segment.models import Segment

class StaffBrowsableAPIMixin:
    def get_renderers(self):
        """
        add BrowsableAPIRenderer if user is staff (regular users see JSONRenderer response)
        """
        # explicitly set renderer to JSONRenderer (the default for non staff users)
        rends = [renderers.JSONRenderer]
        if self.request.user.is_staff:
            # staff users see browsable API
            rends.append(renderers.BrowsableAPIRenderer)
        return [renderer() for renderer in rends]

class SegmentViewSet(StaffBrowsableAPIMixin, viewsets.ReadOnlyModelViewSet):
    queryset = Segment.objects.all()
    serializer_class = serializers.SegmentSerializer

这对所有端点都适用(普通用户通过GET调用端点时,他们只会看到JSON,而无法浏览API)。不幸的是,它不适用于 APIRootView (API的根视图,例如 https://restframework.herokuapp.com/ )。

this works fine for all endpoints (when a regular user calls the endpoint via GET, they only see the JSON, not the browsable API). Unfortunately it does not work for APIRootView (the root view of the api, e.g. https://restframework.herokuapp.com/).

如何在 APIRootView 也是如此?

推荐答案

编辑



了解您的问题更好(我相信),您可以将API的基本URL锁定很简单(mixin可能应该移至另一个文件,但是为了清楚起见,只需将所有内容放在一起):

Edit

Understanding your problem better (I believe), you can lock the base URL of your API down pretty simply (the mixin should probably be moved to another file but just kept everything together for clarity):

# api/urls.py
from django.urls import include, path

from rest_framework import permissions, renderers, routers

from . import views

app_name = 'api'

class StaffBrowsableAPIMixin:
    def get_renderers(self):
        """
        add BrowsableAPIRenderer if user is staff (regular users see JSONRenderer response)
        """
        # explicitly set renderer to JSONRenderer (the default for non staff users)
        rends = [renderers.JSONRenderer]
        if self.request.user.is_staff:
            # staff users see browsable API
            rends.append(renderers.BrowsableAPIRenderer)
        return [renderer() for renderer in rends]


class CustomAPIRootView(StaffBrowsableAPIMixin, routers.APIRootView):
    permission_classes = (permissions.IsAdminUser,)


class CustomDefaultRouter(routers.DefaultRouter):
    APIRootView = CustomAPIRootView

router = CustomDefaultRouter()  # browseable api
router.register('segments', views.SegmentViewSet)
# there are a lot more...

urlpatterns = [
    path('', include(router.urls)),
]

permission_classes 将不会向非管理员用户显示任何终结点,但仍会显示Browsable API模板。要同时删除它,您需要使用 StaffBrowsableAPIMixin 更改渲染器。

The permission_classes will handle not showing any of your endpoints to non-Admin users but the Browsable API template will still be shown. To remove that as well, you need to change the renderer using the StaffBrowsableAPIMixin.

一种方法是使用DRF的渲染器设置和方法。

One way to do this is using DRF's renderer settings and methods.

在您的 settings.py 中:

REST_FRAMEWORK = {
    # Only enable JSON renderer by default.
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
}

,然后在您的 views.py 中:

from rest_framework import generics, renderers

class StaffBrowsableMixin(object):
    def get_renderers(self):
        """
        Add Browsable API renderer if user is staff.
        """
        rends = self.renderer_classes
        if self.request.user and self.request.user.is_staff:
            rends.append(renderers.BrowsableAPIRenderer)
        return [renderer() for renderer in rends]

class CustomListApiView(StaffBrowsableMixin, generics.ListAPIView):
    """
    List view.
    """
    # normal stuff here

,对于希望为st启用BrowsableAPI的任何 APIView 使用 StaffBrowsableMixin

Basically, use StaffBrowsableMixin for any APIView you want the BrowsableAPI to be enabled for staff.

类似的问题,如上面评论中的链接以及我在那的答案: https://stackoverflow.com/a/58762483/4599228

Similar question, as linked above in comments, and my answer there as well: https://stackoverflow.com/a/58762483/4599228

这篇关于Django REST Framework-如何为非员工用户禁用可浏览的API(is_staff = False)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆