当我的检索权限类设置为IsAuthenticated时,为什么DRF在检索请求上返回403?

时间:2019-07-17 19:42:41

标签: https django-rest-framework http-headers

我正在从事一个涉及DRF的项目。我在标准ModelViewset上重写了get_permissions()方法,但是由于我将其设置为IsAuthenticated,因此检索权限似乎无法正常运行,但是如果我提出检索请求,则会收到403响应。

这是我的视图的样子:

class chartView(viewsets.ModelViewSet):
    queryset = chart.objects.all()
    serializer_class = chartSerializer

    def get_permissions(self):
        if self.action == 'list'  or 'create' or 'update' or 'partial_update' or 'destroy':
            permission_classes = [IsAdminUser]
        elif self.action == 'retrieve' :
            permission_classes = [IsAuthenticated]
        return [permission() for permission in permission_classes]

在我的urls.py中,我只使用 Defaultrouter()并注册了如下视图:
router.register('charts',views.chartView)

当我以管理员身份登录时,通过执行以下操作,列表操作可以正常工作:
myurl.com/api/charts
通过执行以下操作,检索操作也可以正常工作:
myurl.com/api/charts/instance

但是当我以非管理员身份登录并尝试访问时:
myurl.com/api/charts/instance
我收到403禁止响应,因为我将检索操作的权限类设置为IsAuthenticated,所以不应发生。

我在settings.py文件中尝试了以下操作:
a:

REST_FRAMEWORK = {
  'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
    'rest_framework.permissions.IsAdminUser',
   ),
  'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.BasicAuthentication',
    'rest_framework.authentication.SessionAuthentication',
   ),
}

b:

REST_FRAMEWORK = {
      'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
       ),
}

1 个答案:

答案 0 :(得分:0)

get_permissions()起,您就有了这样的表达方式

if self.action == 'list'  or 'create' or 'update' or 'partial_update' or 'destroy':
    permission_classes = [IsAdminUser]

它的实际作用是首先处理这些字符串之间的or操作,然后直观地得出True的结果。因此,仅当self.action的值不是False或等于False的其他值时,此表达式才会失败,但这在这里也不会发生,因为self.action将是操作方法名称的值。也就是说,此表达式始终为True,因此导致您的permission_classes始终为IsAdminUser

您可以这样写:

if self.action in ('list', 'create', 'update', 'partial_update', 'destroy'):
    permission_classes = [IsAdminUser]