django 会话过期后如何使用自定义的 login_required 装饰器发送 401 响应?

问题描述 投票:0回答:1

我有一个自定义的 login_required 装饰器,如下所示:

def login_required(function):
    """
    Ensure that user is logged in
    """

    def wrap(request, *args, **kwargs):
        if request.user.is_anonymous:
            message = {
                "status": "error",
                "message": "user login error",
                "data": "user is not logged in",
            }
            return HttpResponse(
                content=json.dumps(message).encode("utf-8"),
                status=401,
                headers=None,
                content_type="application/json",
            )
        return function(request, *args, **kwargs)

    return wrap

当我的请求传入且 django 会话已过期时,我会在响应中看到我的自定义消息。然而,响应的状态码是 302,通过 url 中的

/accounts/login/?next=
进行重定向。

我已在设置中配置了 SESSION_TIMEOUT_REDIRECT、LOGOUT_REDIRECT、LOGIN_URL。我尝试过配置不同的 django 设置,但到目前为止没有成功。

这是我正在使用的中间件:

MIDDLEWARE = [
    "csp.middleware.CSPMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django_session_timeout.middleware.SessionTimeoutMiddleware",
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",
    "core.middleware.admin_pages_middleware.AdminPagesMiddleware",
]

技术堆栈

  • Python 3.12
  • Django 5.0

我希望我的回复是 401 而不是 302。您能让我知道我错过了什么吗?谢谢!

python django django-sessions
1个回答
0
投票

您的 302 响应来自

django_session_timeout.middleware.SessionTimeoutMiddleware
中间件,我猜它来自 这个包。由于中间件在视图之前运行,因此您的视图永远没有机会运行。

鉴于您似乎不想在会话过期时重定向用户,您不妨取消它,只需将

SESSION_COOKIE_AGE
设置 设置为适当的值以使用户会话过期或者如果您正在使用他们的软件包具有在“最后一次活动”后 N 秒使会话过期的功能,您需要分叉他们的软件包并更改他们的中间件(存在于此文件中)以返回您的自定义响应而不是重定向用户。

© www.soinside.com 2019 - 2024. All rights reserved.