如果用户无权查看实例,则回复 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
,这是一个视图的混合类,它将检查用户是否具有指定的权限并处理他们没有的情况。
因为PermissionRequiredMixin
是AccessMixin
的子类,也许可以创建一个新的特定混合类来覆盖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_403
和return_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的主要内容,如果未能解决你的问题,请参考以下文章
Linux 出现command not found 错误解决
ifconfig: command not found 如何解决?