如果用户无权查看实例,则回复 Not Found

Posted

技术标签:

【中文标题】如果用户无权查看实例,则回复 Not Found【英文标题】:Respond with Not Found if user is not authorised to view the instance 【发布时间】:2020-12-14 19:40:46 【问题描述】:

我如何修改 Django 行为,仅针对 一些 模型,以隐藏该模型中除用户有权查看的对象之外的任何对象?

默认情况下,Django 将使用 404 Not Found 响应对不存在对象的查询,以及用户无权查看的现有对象,与 403 Forbidden.

这适用于典型的 Django 视图和专用视图(如 Django REST 框架)。这都是正确的,默认情况下。

不过,我想做的是向每个用户展示一些特定的模型,因为只包含用户可以查看的记录,其中没有其他内容可供查询。如果他们被授权查看实例,则会显示;如果它存在但未经授权,那么 Django 甚至不应该透露该实例是否存在,并且应该只用 404 Not Found 响应。

此要求仅适用于数据库中的部分模型。例如,机密文件:访问者不应四处嗅探并发现哪些文件存在,哪些文件不存在。要么他们有权查看该文档,要么不应该告诉他们那里有任何东西,就好像他们查询了一个不存在的文档一样。

对于其他模型,正常行为是正确的(如果未找到则为 404,如果存在则为 403 但当前用户未授权)。

因此,全局覆盖异常行为的解决方案不适用于此问题。

如何说服 Django 将特定模型视为“未经授权的访问看起来像不存在的实例”?

【问题讨论】:

这能回答你的问题吗? Django REST Framework - How to return 404 error instead of 403 部分,我想。您能否回答这个问题,该问题具体指出此行为应仅适用于某些模型而不适用于所有请求? 【参考方案1】:

Django 的权限系统包括PermissionRequiredMixin,这是一个视图的混合类,它将检查用户是否具有指定的权限并处理他们没有的情况。

因为PermissionRequiredMixinAccessMixin 的子类,也许可以创建一个新的特定混合类来覆盖AccessMixin.handle_no_permission

from django.contrib.auth.mixins import PermissionRequiredMixin

class PermissionRequiredOrDoesNotExistMixin(PermissionRequiredMixin):
    """ A mix-in class that handles “not permitted” as though it were “not found”. """

    def handle_no_permission(self):
        ...

【讨论】:

【参考方案2】:

第三方库django-guardian为视图实现了一个自定义的PermissionRequiredMixin(这个类是django.contrib.auth.mixins.PermissionRequiredMixin的子类)。

该自定义类具有return_403return_404 属性,以指定视图应在用户没有所需权限时返回其中一个HTTP 响应(而不是重定向到登录页面的默认行为)。

【讨论】:

【参考方案3】:

是,或者:

from django.views import View 
from django.contrib.auth.mixins import UserPassesTestMixin
from django.http import Http404


class StaffRequired(UserPassesTestMixin):

    def test_func(self):
        return self.request.user.is_staff

    def handle_no_permission(self):
        raise Http404


class HiddenView(StaffRequired, View):
    pass

【讨论】:

以上是关于如果用户无权查看实例,则回复 Not Found的主要内容,如果未能解决你的问题,请参考以下文章

command not found啥意思

Linux 出现command not found 错误解决

ifconfig: command not found 如何解决?

系统之家Ubuntu sudo报错command not found怎么办?怎么办

解决mac下adb: command not found

Python3: Command not found(Mac OS)