Django переключается между состоянием аутентифицированной и неаутентифицированной сессий
При просмотре моего сайта или при обновлении страницы случается, что Django забывает о состоянии аутентификации и возвращает страницу, которую увидел бы анонимный пользователь. При повторном обновлении страницы она либо возвращается к авторизованной сессии, либо продолжает показывать состояние без аутентификации. Это случайный случай.
Я проверил заголовки запросов, которые посылает браузер, и sessionid
присутствует в каждом запросе. Даже когда цикл меняется с authenticated
→ unauthenticated
→ authenticated
, sessionid
остается тем же. Таким образом, сессия не удаляется и не очищается из бэкенда сессий, потому что идентификатор сессии все еще может быть использован после просмотра страницы в анонимном состоянии. Сессия просто не подхватывается Django.
Веб-сайт размещен на render.com, платформе как услуга, такой же, как Heroku или fly.io. В журналах приложения я заметил сообщение Session data corrupted
. Метрики показывали, что включилось автомасштабирование, и было три экземпляра приложения.
Это означает, что один из трех экземпляров смог вернуть страницу в аутентифицированном состоянии, принадлежащую cookie session
, в то время как два других экземпляра не смогли и вместо этого вернули Session data corrupted
.
Django использует settings.SECRET_KEY
для подписи сессионных cookies. К сожалению, я допустил ошибку, задав случайный секретный ключ:
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", get_random_secret_key())
Это означало не только то, что при каждом развертывании создавалась новая SECRET_KEY
, убивая все существующие сессии. Но также и то, что экземпляры не смогут использовать сессию, созданную другим экземпляром, поскольку подписи не будут совпадать, и таким образом пользователи будут циклически переходить из аутентифицированного состояния в неаутентифицированное
Решением этой проблемы является установка определенного SECRET_KEY
в окружении.