权限类装饰器将被忽略。 “未提供身份验证凭据”响应

时间:2019-08-19 05:45:02

标签: django django-rest-framework permissions

我将Django Rest Framework用于我的API服务。在我的settings.py中,我有以下REST_FRAMEWORK设置:

REST_FRAMEWORK = {
    ...
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated'
    )
    ...
}

现在,我想更改权限类别,以允许任何人使用一个视图。我用过@permission_classes装饰器。

class UserViewSet(viewsets.ModelViewSet):

    serializer_class = RegisterSerializer
    queryset = User.objects.all()

    @permission_classes([permissions.AllowAny,])
    def create(self, request, *args, **kwargs):
        data = request.data
        ...

我应该能够在没有任何权限的情况下执行创建操作。而是在尝试访问API时收到身份验证错误。

    "detail": "Authentication credentials were not provided."

根据docs,@ permission_classes装饰器是此类权限替代的正确方法。这是Django 2.2.4和DRF 3.10.2。

编辑

我忘记提及我不想允许任何人访问任何视图,仅允许选择的视图访问。大多数视图应具有全局设置的IsAuthenticated权限。

5 个答案:

答案 0 :(得分:4)

可以使用DEFAULT_PERMISSION_CLASSES设置在全局范围内设置默认权限策略。例如。

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

如果未指定,则此设置默认为允许不受限制的访问:

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

有关更多参考,您可以检查DRF文档doc

编辑:

您可以使用自己的类来覆盖该权限,

from rest_framework import permissions

class SkipAuth(permissions.IsAuthenticated):
    def has_permission(self, request, view):
    return True

并使用此类跳过特定功能的身份验证,例如:

@permission_classes([SkipAuth])
def create(self, request, *args, **kwargs):
   data = request.data
   ...

答案 1 :(得分:3)

您可以覆盖get_permission方法

class UserViewSet(viewsets.ModelViewSet):

  serializer_class = RegisterSerializer
  queryset = User.objects.all()

  def get_permissions(self):
    if self.request.method == 'POST':  # remove default permission from post method(Create method)
       return []
    return [permission() for permission in self.permission_classes]

  def create(self, request, *args, **kwargs):
    data = request.data
    ...

答案 2 :(得分:2)

您已将权限级别指定为IsAuthenticated,但您想将其允许给任何用户,因此您必须从设置中删除该权限,默认情况下django将允许任何权限,或者您可以将其更改为

'DEFAULT_PERMISSION_CLASSES': [
   'rest_framework.permissions.AllowAny',
]

有关更多信息,请参见docs

答案 3 :(得分:2)

在视图集中,应使用<html> <head> <script src='js_use/sigma.js'></script> <script src = 'js_use/sigma.min.js'></script> <script src='js_use/sigma.utils.js'></script> <script src = 'js_use/sigma.parsers.json.min.js'></script> <script src = 'js_use/sigma.require.js'></script> </head> <body> <div id = "container"> </div> <script> g = { "nodes": [ { "id": "node_apple", "label": "Apple_Inc.", "x": 10, "y": 8, "size": 5 }, { "id": "node_steve_jobs", "label": "Steve_Jobs", "x": 14, "y": 8, "size": 5 }, { "id": "node_public_company", "label": "Public_Company", "x": 7, "y": 5, "size": 2 } ], "edges": [ { "id": "e0", "source": "node_apple", "target": "node_steve_jobs" }, { "id": "e1", "source": "node_apple", "target": "node_public_company" }, { "id": "e2", "source": "node_steve_jobs", "target": "node_apple" } ] } const s=new sigma({ graph : g, container : 'container' }); s.refresh(); </script> </body> </html> 类属性而不是方法装饰器。

所以您的UserViewSet看起来像:

permission_classes

在这种情况下,该权限应该可以按您期望的方式工作。

答案 4 :(得分:2)

您可以覆盖所需视图功能的check_permission方法并实现该方法。

class UserViewSet(viewsets.ModelViewSet):

    serializer_class = RegisterSerializer
    queryset = User.objects.all()

    def check_permissions(self, request):
       if self.action and (self.action == 'create'):
          return True // allow any
       return super().check_permissions(request)

    def create(self, request, *args, **kwargs):
        data = request.data
        ...