Как отправить 401 ответ с пользовательским декоратором login_required после истечения срока действия сессии Django?

У меня есть пользовательский декоратор 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, перенаправление с /accounts/login/?next= в URL.

Я настроил 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.

Не могли бы вы сообщить мне, чего мне не хватает?

Ваш ответ 302 приходит от django_session_timeout.middleware.SessionTimeoutMiddleware промежуточного ПО, которое, как я полагаю, происходит из этого пакета. Поскольку промежуточное ПО запускается до представления, ваше представление никогда не получит шанс запуститься.

Учитывая, что вы, похоже, не хотите перенаправлять пользователя, когда истекает его сессия, вы можете обойтись без этого и просто установить SESSION_COOKIE_AGE параметр в соответствующее значение для истечения сессии пользователя или, если вы используете их пакет для его функции пакет для его функции истечения сессии через N секунд после "последней активности", вам нужно будет форкнуть их пакет и изменить их промежуточное ПО (присутствует в этом файле), чтобы вернуть ваш пользовательский ответ вместо перенаправления пользователя.

Вернуться на верх