如何将Django Rest Framework可浏览的API接口限制为管理员用户

时间:2015-07-19 23:56:47

标签: python django security django-rest-framework

我正在为移动应用开发Django Rest Framework后端。 API是私有的,只能在内部使用。

可浏览的API便于帮助开发人员处理项目,但我希望阻止任何未设置为项目管理员的人使用可浏览界面。

我意识到可浏览的管理员不会授予用户不会拥有的任何权限,但它确实有一些安全灰色区域(例如,对于具有外键关系的模型,HTML选择器字段会填充所有DB中可能的相关对象,除非您明确指示不要)。

由于此应用处理敏感的用户数据,我更愿意向公众公开可能的最小表面区域,以降低我自己潜在错误疏忽的风险。

有没有办法为非管理员用户禁用可浏览的API而不为每个人禁用它?我已经做了大量的Google搜索并查看了SO并且没有找到答案。这个问题很接近How to disable admin-style browsable interface of django-rest-framework?但不一样,因为这些说明会禁用每个人的界面。

3 个答案:

答案 0 :(得分:1)

“ DEFAULT_PERMISSION_CLASSES”设置是否不够?这为所有视图DRF docs on default permission classes

设置了默认限制

settings.py中:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAdminUser',
    ]
}

它们将“到达”可浏览的界面,但是如果未经授权,所有类型的请求都将被拒绝。

如果非管理员用户出于某种原因需要达到各种端点,则可以逐个视图地放宽限制。

答案 1 :(得分:1)

假设您使用的是DRF的内置视图,我认为您可以覆盖get_renderers()

在您的设置文件中:

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

答案 2 :(得分:0)

rest_framework次观看中,我们有一个名为renderes_classes的属性 通常我们使用方法get_<something>queryset / get_queryset一样,但在这种情况下我们没有,所以我需要实现一个属性。

from tasks.models import Task
from tasks.serializers import TaskSerializer

from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.renderers import CoreJSONRenderer


class CustomRendererView:
    permission_classes = (IsAuthenticatedOrReadOnly,)

    @property
    def renderer_classes(self):
        renderers = super(ListTask, self).renderer_classes

        if not self.request.user.is_staff:
            renderers = [CoreJSONRenderer]

        return renderers


class ListTask(CustomRendererView, ListAPIView):
    queryset = Task.objects.all()
    serializer_class = FullTaskSerializer