有没有办法在仍然可以访问api端点的同时限制对DRF接口的访问?

时间:2019-06-10 13:13:00

标签: javascript django reactjs django-rest-framework

我正在创建一个以Django Rest Framework作为后端和ReactJS作为前端的站点。我有多个用于存储各种数据的api端点,即

/api/
/api/users/
/api/objects/
/api/other_objects/
etc

我不希望普通用户直接访问DRF界面。如果有人决定转到这些url中的一个,则我希望将其重定向到索引页面(如果它们没有人员身份)。

我尝试使用视图中的装饰器重定向用户:

from django.contrib.auth.decorators import user_passes_test

def staff_check(user):
    if user.is_authenticated and user.is_staff:
        return True
    else:
        return False

@user_passes_test(staff_check, login_url='/', redirect_field_name=None)
@api_view(['GET'])
def api_root(request, format=None):
    return Response({
        'users': reverse('user-list', request=request, format=format),
        'objects': reverse('objects-list', request=request, format=format),
        'other_objects': reverse('other-objects-list', request=request, format=format)
    })

就重定向而言,它可以正常工作,但是当我的React应用尝试使用装饰器从端点获取数据时,它也会被重定向。

我知道我可以改为在视图上设置权限,即

class ObjectsList(generics.ListCreateAPIView):
    queryset = Object.objects.all().order_by('created')
    serializer_class = ObjectSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

但是,它仍然允许用户查看界面(有无内容,取决于权限)。有没有一种方法可以使端点可以访问React的fetch命令而无需重定向,但是当用户尝试查看界面时仍可以重定向用户?

2 个答案:

答案 0 :(得分:0)

只需更改渲染器类并从列表中删除默认的BrowsableAPIRenderer

在全球范围内,像这样:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    )
}

但是,在您的情况下,您可以使用装饰器在每个视图中控制它(当界面应该显示或不显示时):

@api_view(['GET'])
@renderer_classes((JSONRenderer, BrowsableAPIRenderer))
def your_view(request, format=None):
   ...

答案 1 :(得分:0)

添加到 Danilo Akamine 答案,在开发过程中限制对 DRF 的直接访问是没有必要的。

然而,在生产环境中,渲染 HTML 表单会占用大量 CPU,这会阻止/减慢 Django Rest 框架中的其他请求。

为了更好地服务于此,我们可以将以下代码添加到 settings.py

if not DEBUG:
    REST_FRAMEWORK['DEFAULT_RENDERER_CLASSES'] =['rest_framework.renderers.JSONRenderer', ]