Django - 当页面不存在或用户未通过身份验证时返回更改答案

Posted

技术标签:

【中文标题】Django - 当页面不存在或用户未通过身份验证时返回更改答案【英文标题】:Django - change answer returned when a page doesn't exist or user is not authenticated 【发布时间】:2021-01-06 08:47:42 【问题描述】:

我在生产中使用 Django。

我发现如果未经身份验证的用户访问公开的 API - 服务器将返回 HTTP 401 Unauthorized。

如果用户将访问一个不存在的 API(有或没有身份验证)- 服务器将返回 404 Not found。

在我看来,这似乎是一种糟糕的安全做法,并且允许攻击者找到服务器公开的 API。

有没有办法改变它,所以两者都会返回完全相同的结果(我认为 401 是最佳做法,不是吗?)

【问题讨论】:

【参考方案1】:

我会在 Django 服务器中创建一个回退 URL 以匹配所有非确定性 URL

from django.contrib import admin
from django.http.response import JsonResponse
from django.urls import path, re_path


def not_found_json(request, any_path=None):
    return JsonResponse('message': 'not allowed', status=403)


urlpatterns = [
    path('admin/', admin.site.urls),
    # app1 urls
    # app2 urls
    # app3 urls
    # at last,
    re_path(r'(?P<any_path>.+)', not_found_json, name='not-found-json'),
]

注意事项

    此备用 URL 定义必须在您的 ROOT_URLCONF--(Django doc) 中 模式表达式必须在列表底部 使用403Forbidden,比401Unauthorized更合适

【讨论】:

我接受了这个答案。但我要补充一点:1.为了使其与 django 在没有正确权限时返回的答案更加一致,应该返回 Unauthorized。就是这样:***.com/a/14263766/972014 2. 还应该在 django-rest-framework 中禁用 BrowsableAPIRenderer,如下所述:***.com/a/49395080/972014 我强烈反对 Unauthorized(参考:401 Unauthorized vs 403 Forbidden)。在您的情况下,用户可能已登录,但他必须没有正确的权限 另外,JsonResponse 不会呈现任何 Browsable API,因为它带有裸 Django,而不是 DRF。 关于未经授权的 - 我现在明白了。你说的对。关于 Browsable - 在默认配置中支持 browsable,因此在浏览器中直接导航到 API 将公开有关它的信息。 您可以使用或不使用可浏览选项来呈现 API,它与 回退逻辑 无关。但是,我承认禁用可浏览 API 是一个不错的选择,我在我的项目中也这样做了。除此之外,我的观点是可浏览的 API 渲染仅适用于 DRF 视图/API,而这里的 not_found_json(...) 不是 DRF 视图/API。

以上是关于Django - 当页面不存在或用户未通过身份验证时返回更改答案的主要内容,如果未能解决你的问题,请参考以下文章

Django 身份验证 - 错误的重定向 url 到登录页面

Django身份验证和Ajax - 需要登录的URL

django redirect_authenticated_user

Laravel - 用户未通过身份验证时如何重定向到所需页面

web安全未授权访问&身份验证&访问控制

视图之间的Django身份验证