【问题标题】:Why does the DRF return 403 on a retrieve request when my permissionclass for retrieve is set to IsAuthenticated?当我的检索权限类设置为 IsAuthenticated 时,为什么 DRF 在检索请求上返回 403?
【发布时间】:2019-07-17 19:42:41
【问题描述】:

我正在从事一个涉及 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.请确保您正确格式化您的代码。 2. 回复内容是什么? 403 可能有几个原因,例如 CSRF 问题
  • 你不应该像这样使用or 操作。您的表达式等价于self.action == True,因为True 将是该部分的逻辑运算结果。相反,您可以使用self.action in ('list', 'create', ...) 来满足您的要求
  • @Linovia 我的代码格式有什么问题?

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


【解决方案1】:

既然在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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-16
    • 2014-04-30
    • 2019-05-09
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多