Как использовать сеансы
Django полностью поддерживает анонимные сеансы. Инфраструктура сеансов позволяет хранить и получать произвольные данные отдельно для каждого посетителя сайта. Данные хранятся на стороне сервера, а отправка и получение файлов cookie абстрагированы. Файлы cookie содержат идентификатор сеанса, а не сами данные (если только вы не используете серверную часть на основе файлов cookie).
Включение сеансов
Сеансы реализованы с помощью компонента промежуточного ПО.
Чтобы включить функциональность сеансов, выполните следующие действия:
- Измените настройку
MIDDLEWAREи убедитесь, что она содержит'django.contrib.sessions.middleware.SessionMiddleware'. В настройкеsettings.pyпо умолчанию, созданной с помощьюdjango-admin startproject,SessionMiddlewareуже активировано.
Если вы не хотите использовать сеансы, можно также удалить строку SessionMiddleware из MIDDLEWARE и 'django.contrib.sessions' из INSTALLED_APPS. Это позволит немного сократить накладные расходы.
Настройка механизма сеансов
По умолчанию Django хранит сеансы в базе данных (используя модель django.contrib.sessions.models.Session). Это удобно, но в некоторых конфигурациях хранить данные сеансов в другом месте быстрее, поэтому Django можно настроить на хранение данных сеансов в файловой системе или в кэше.
Использование сеансов с хранением в базе данных
Чтобы использовать сеансы с хранением в базе данных, необходимо добавить 'django.contrib.sessions' в настройку INSTALLED_APPS.
После настройки проекта выполните команду manage.py migrate, чтобы создать единственную таблицу базы данных, в которой хранятся данные сеансов.
Использование кэшированных сеансов
Для повышения производительности можно использовать серверную часть сеансов на основе кэша.
Чтобы хранить данные сеансов с помощью системы кэширования Django, сначала необходимо убедиться, что кэш настроен; подробности см. в документации по кэшированию.
Предупреждение
Используйте сеансы на основе кэша только в том случае, если применяется серверная часть кэша Memcached или Redis. Серверная часть кэша в локальной памяти не хранит данные достаточно долго, чтобы быть подходящим выбором. Кроме того, вместо передачи всех данных через серверные части кэша на основе файлов или базы данных будет быстрее напрямую использовать сеансы на основе файлов или базы данных. Также серверная часть кэша в локальной памяти НЕ является безопасной для многопроцессной работы, поэтому, вероятно, не подходит для производственной среды.
Если в CACHES определено несколько кэшей, Django будет использовать кэш по умолчанию. Чтобы использовать другой кэш, задайте для SESSION_CACHE_ALIAS имя этого кэша.
После настройки кэша необходимо выбрать между кэшем с резервным хранением в базе данных и непостоянным кэшем.
Серверная часть кэширования с базой данных (cached_db) использует кэш с записью одновременно в кэш и базу данных — сначала изменения сеанса применяются к базе данных, а затем к кэшу. Если запись в кэш завершается с ошибкой, исключение перехватывается и регистрируется с помощью регистратора сеансов, чтобы не нарушать в остальном успешную операцию записи.
При чтении сеанса используются данные из кэша или из базы данных, если данные были вытеснены из кэша. Чтобы использовать эту серверную часть, задайте для SESSION_ENGINE значение "django.contrib.sessions.backends.cached_db" и следуйте инструкциям по настройке для сеансов с хранением в базе данных.
Серверная часть кэша (cache) хранит данные сеансов только в кэше. Это быстрее, поскольку не требует сохранения данных в базе, но необходимо учитывать, что произойдёт при вытеснении данных из кэша. Вытеснение может произойти, если кэш заполнится или сервер кэша будет перезапущен; в результате данные сеансов будут потеряны, в том числе пользователи выйдут из системы. Чтобы использовать эту серверную часть, задайте для SESSION_ENGINE значение "django.contrib.sessions.backends.cache".
Серверную часть кэша можно сделать постоянной, используя постоянный кэш, например Redis с соответствующей конфигурацией. Однако, если вы не уверены, что кэш настроен на достаточную степень сохранности данных, выберите серверную часть кэширования с базой данных. Это позволит избежать проблемных случаев, связанных с ненадёжным хранением данных в производственной среде.
Использование сеансов на основе файлов
Чтобы использовать сеансы на основе файлов, задайте для настройки SESSION_ENGINE значение "django.contrib.sessions.backends.file".
Также можно задать настройку SESSION_FILE_PATH (по умолчанию используется результат tempfile.gettempdir(), скорее всего, /tmp), чтобы указать, где Django будет хранить файлы сеансов. Убедитесь, что веб-сервер имеет права на чтение и запись в этом расположении.
Использование сеансов в представлениях
Если активировано SessionMiddleware, у каждого объекта HttpRequest — первого аргумента любой функции-представления Django — будет атрибут session, представляющий собой объект, похожий на словарь.
Вы можете читать и изменять request.session в любой момент выполнения представления. Его можно изменять несколько раз.
-
class backends.base.SessionBase -
Это базовый класс для всех объектов сеансов. Он предоставляет следующие стандартные методы словаря:
-
__getitem__(key) -
Пример:
fav_color = request.session['fav_color']
-
__setitem__(key, value) -
Пример:
request.session['fav_color'] = 'blue'
-
__delitem__(key) -
Пример:
del request.session['fav_color']. Если указанногоkeyещё нет в сеансе, возникаетKeyError.
-
__contains__(key) -
Пример:
'fav_color' in request.session
-
get(key, default=None)
-
aget(key, default=None) -
Асинхронная версия:
aget()Пример:
fav_color = request.session.get('fav_color', 'red')
-
aset(key, value) -
Пример:
await request.session.aset('fav_color', 'red')
-
update(dict)
-
aupdate(dict) -
Асинхронная версия:
aupdate()Пример:
request.session.update({'fav_color': 'red'})
-
pop(key, default=__not_given)
-
apop(key, default=__not_given) -
Асинхронная версия:
apop()Пример:
fav_color = request.session.pop('fav_color', 'blue')
-
keys()
-
akeys() -
Асинхронная версия:
akeys()
-
values()
-
avalues() -
Асинхронная версия:
avalues()
-
has_key(key)
-
ahas_key(key) -
Асинхронная версия:
ahas_key()
-
items()
-
aitems() -
Асинхронная версия:
aitems()
-
setdefault()
-
asetdefault() -
Асинхронная версия:
asetdefault()
-
clear()
Кроме того, доступны следующие методы:
-
flush()
-
aflush() -
Асинхронная версия:
aflush()Удаляет текущие данные сеанса из хранилища и удаляет файл cookie сеанса. Используйте этот метод, если хотите гарантировать, что прежние данные сеанса больше нельзя будет получить из браузера пользователя (например, его вызывает функция
django.contrib.auth.logout()).
-
set_test_cookie()
-
aset_test_cookie() -
Асинхронная версия:
aset_test_cookie()Устанавливает тестовый файл cookie, чтобы определить, поддерживает ли браузер пользователя файлы cookie. Из-за принципа работы файлов cookie проверить это можно будет только при следующем запросе страницы пользователем. Дополнительные сведения см. ниже в разделе Установка тестовых файлов cookie.
-
test_cookie_worked()
-
atest_cookie_worked() -
Асинхронная версия:
atest_cookie_worked()Возвращает
TrueилиFalseв зависимости от того, принял ли браузер пользователя тестовый файл cookie. Из-за принципа работы файлов cookie необходимо вызватьset_test_cookie()илиaset_test_cookie()при предыдущем, отдельном запросе страницы. Дополнительные сведения см. ниже в разделе Установка тестовых файлов cookie.
-
delete_test_cookie()
-
adelete_test_cookie() -
Асинхронная версия:
adelete_test_cookie()Удаляет тестовый файл cookie. Используйте этот метод для очистки после проверки.
-
get_session_cookie_age() -
Возвращает значение настройки
SESSION_COOKIE_AGE. Это значение можно переопределить в пользовательской серверной части сеансов.
-
set_expiry(value)
-
aset_expiry(value) -
Асинхронная версия:
aset_expiry()Задаёт время истечения срока действия сеанса. Можно передать несколько разных типов значений:
- Если
value— целое число, срок действия сеанса истечёт после указанного количества секунд бездействия. Например, вызовrequest.session.set_expiry(300)приведёт к тому, что срок действия сеанса истечёт через 5 минут. - Если
value— объектdatetimeилиtimedelta, срок действия сеанса истечёт в указанную дату и время. - Если
value— это0, срок действия файла cookie сеанса пользователя истечёт при закрытии браузера. - Если
value— этоNone, для сеанса снова будет применяться глобальная политика истечения срока действия.
Чтение сеанса не считается активностью при расчёте срока действия. Срок истечения сеанса рассчитывается от момента его последнего изменения.
- Если
-
get_expiry_age()
-
aget_expiry_age() -
Асинхронная версия:
aget_expiry_age()Возвращает количество секунд до истечения срока действия этого сеанса. Для сеансов без заданного срока действия (или для сеансов, срок действия которых истекает при закрытии браузера) это значение будет равно
SESSION_COOKIE_AGE.Эта функция принимает два необязательных именованных аргумента:
-
modification: время последнего изменения сеанса в виде объектаdatetime. По умолчанию используется текущее время. -
expiry: сведения о сроке действия сеанса в виде объектаdatetime, объектаint(в секундах) илиNone. По умолчанию используется значение, сохранённое в сеансе с помощьюset_expiry()/aset_expiry(), если оно есть, илиNone.
Примечание
Этот метод используется серверными частями сеансов для определения срока действия сеанса в секундах при его сохранении. Он не предназначен для использования вне этого контекста.
В частности, хотя можно определить оставшееся время жизни сеанса, если только у вас есть корректное значение
modification, аexpiryзадан как объектdatetime, когда у вас есть значениеmodification, проще вычислить срок действия вручную:expires_at = modification + timedelta(seconds=settings.SESSION_COOKIE_AGE)
-
-
get_expiry_date()
-
aget_expiry_date() -
Асинхронная версия:
aget_expiry_date()Возвращает дату истечения срока действия этого сеанса. Для сеансов без заданного срока действия (или для сеансов, срок действия которых истекает при закрытии браузера) это будет дата, наступающая через
SESSION_COOKIE_AGEсекунд от текущего момента.Эта функция принимает те же именованные аргументы, что и
get_expiry_age(); к её использованию применимы аналогичные замечания.
-
get_expire_at_browser_close()
-
aget_expire_at_browser_close() -
Асинхронная версия:
aget_expire_at_browser_close()Возвращает
TrueилиFalseв зависимости от того, истекает ли срок действия файла cookie сеанса пользователя при закрытии браузера.
-
clear_expired()
-
aclear_expired() -
Асинхронная версия:
aclear_expired()Удаляет из хранилища сеансы с истёкшим сроком действия. Этот метод класса вызывается командой
clearsessions.
-
cycle_key()
-
acycle_key() -
Асинхронная версия:
acycle_key()Создаёт новый ключ сеанса, сохраняя текущие данные сеанса. Метод вызывается функцией
django.contrib.auth.login()для защиты от фиксации сеанса.
-
Сериализация сеансов
По умолчанию Django сериализует данные сеансов в формате JSON. Настройку SESSION_SERIALIZER можно использовать для изменения формата сериализации сеансов. Несмотря на оговорки, описанные в разделе Создание собственного сериализатора, мы настоятельно рекомендуем использовать сериализацию JSON, особенно если вы используете серверную часть на основе файлов cookie.
Например, при использовании pickle для сериализации данных сеансов возможен следующий сценарий атаки. Если вы используете серверную часть сеансов с подписанными файлами cookie, а злоумышленнику известна настройка SECRET_KEY (или любой ключ из SECRET_KEY_FALLBACKS; в Django нет встроенной уязвимости, которая привела бы к утечке этого ключа), злоумышленник может вставить в свой сеанс строку, которая при десериализации выполнит произвольный код на сервере. Способ сделать это прост и легко доступен в интернете. Хотя хранилище сеансов в файлах cookie подписывает хранящиеся в них данные для защиты от подделки, утечка SECRET_KEY немедленно превращается в уязвимость удалённого выполнения кода.
Встроенные сериализаторы
-
class serializers.JSONSerializer -
Обёртка над сериализатором JSON из
django.core.signing. Поддерживает сериализацию только базовых типов данных.Кроме того, поскольку JSON поддерживает только строковые ключи, учтите, что использование нестроковых ключей в
request.sessionне даст ожидаемого результата:>>> # initial assignment >>> request.session[0] = "bar" >>> # subsequent requests following serialization & deserialization >>> # of session data >>> request.session[0] # KeyError >>> request.session["0"] 'bar'
Аналогично, нельзя хранить данные, которые невозможно закодировать в JSON, например байты, не являющиеся UTF-8, такие как
'\xd9'(что вызываетUnicodeDecodeError).Дополнительные сведения об ограничениях сериализации JSON см. в разделе Создание собственного сериализатора.
Создание собственного сериализатора
Обратите внимание, что JSONSerializer не поддерживает произвольные типы данных Python. Как это часто бывает, приходится искать компромисс между удобством и безопасностью. Если вы хотите хранить в сеансах на основе JSON более сложные типы данных, в том числе datetime и Decimal, необходимо написать собственный сериализатор (или преобразовать такие значения в объект, сериализуемый в JSON, прежде чем сохранять их в request.session). Хотя сериализовать такие значения обычно несложно (может пригодиться DjangoJSONEncoder), написание декодера, который надёжно восстанавливает исходное значение, — более хрупкая задача. Например, есть риск вернуть datetime, хотя на самом деле это была строка, случайно совпавшая с выбранным форматом для datetime).
Класс сериализатора должен реализовать два метода — dumps(self, obj) и loads(self, data), предназначенные соответственно для сериализации и десериализации словаря данных сеанса.
Рекомендации по работе с объектом сеанса
- Используйте обычные строки Python в качестве ключей словаря в
request.session. Это скорее соглашение, чем строгое правило. - Ключи словаря сеанса, начинающиеся с подчёркивания, зарезервированы для внутреннего использования Django.
- Не переопределяйте
request.sessionновым объектом и не обращайтесь к его атрибутам и не задавайте их. Используйте его как словарь Python.
Примеры
Это простое представление задаёт переменной has_commented значение True после того, как пользователь оставил комментарий. Оно не позволяет пользователю оставить комментарий более одного раза:
def post_comment(request, new_comment):
if request.session.get("has_commented", False):
return HttpResponse("You've already commented.")
c = comments.Comment(comment=new_comment)
c.save()
request.session["has_commented"] = True
return HttpResponse("Thanks for your comment!")
Это простое представление выполняет вход «участника» сайта:
def login(request):
m = Member.objects.get(username=request.POST["username"])
if m.check_password(request.POST["password"]):
request.session["member_id"] = m.id
return HttpResponse("You're logged in.")
else:
return HttpResponse("Your username and password didn't match.")
…А это представление выполняет выход участника согласно описанному выше login():
def logout(request):
try:
del request.session["member_id"]
except KeyError:
pass
return HttpResponse("You're logged out.")
Стандартная функция django.contrib.auth.logout() на самом деле делает немного больше, чем приведённый пример, чтобы предотвратить случайную утечку данных. Она вызывает метод flush() объекта request.session. Этот пример демонстрирует работу с объектами сеансов, а не является полноценной реализацией logout().
Использование сессий вне представлений
Примечание
В примерах этого раздела объект SessionStore напрямую импортируется из бэкенда django.contrib.sessions.backends.db. В собственном коде рассмотрите возможность импортировать SessionStore из движка сессий, указанного в настройке SESSION_ENGINE, как показано ниже:
>>> from importlib import import_module >>> from django.conf import settings >>> SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
Для работы с данными сессии вне представления доступен API:
>>> from django.contrib.sessions.backends.db import SessionStore >>> s = SessionStore() >>> # stored as seconds since epoch since datetimes are not serializable in JSON. >>> s["last_login"] = 1376587691 >>> s.create() >>> s.session_key '2b1189a188b44ad18c35e113ac6ceead' >>> s = SessionStore(session_key="2b1189a188b44ad18c35e113ac6ceead") >>> s["last_login"] 1376587691
SessionStore.create() предназначен для создания новой сессии (то есть сессии, не загруженной из хранилища сессий и имеющей session_key=None). save() предназначен для сохранения существующей сессии (то есть сессии, загруженной из хранилища сессий). Вызов save() для новой сессии тоже может сработать, но существует небольшая вероятность, что будет создан session_key, совпадающий с существующим. create() вызывает save() и выполняет цикл, пока не будет сгенерирован неиспользуемый session_key.
Если вы используете бэкенд django.contrib.sessions.backends.db, каждая сессия является обычной моделью Django. Модель Session определена в файле django/contrib/sessions/models.py. Поскольку это обычная модель, сессии можно получать с помощью стандартного API баз данных Django:
>>> from django.contrib.sessions.models import Session >>> s = Session.objects.get(pk="2b1189a188b44ad18c35e113ac6ceead") >>> s.expire_date datetime.datetime(2005, 8, 20, 13, 35, 12)
Обратите внимание, что для получения словаря сессии необходимо вызвать get_decoded(). Это необходимо, поскольку словарь хранится в закодированном виде:
>>> s.session_data
'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
>>> s.get_decoded()
{'user_id': 42}
Когда сохраняются сессии
По умолчанию Django сохраняет данные в базе данных сессий, только если сессия была изменена, то есть если значения в её словаре были присвоены или удалены:
# Session is modified.
request.session["foo"] = "bar"
# Session is modified.
del request.session["foo"]
# Session is modified.
request.session["foo"] = {}
# Gotcha: Session is NOT modified, because this alters
# request.session['foo'] instead of request.session.
request.session["foo"]["bar"] = "baz"
В последнем случае из приведённого выше примера можно явно сообщить объекту сессии, что он был изменён, установив атрибут modified объекта сессии:
request.session.modified = True
Чтобы изменить это поведение по умолчанию, установите для параметра SESSION_SAVE_EVERY_REQUEST значение True. Если установлено значение True, Django будет сохранять сессию в базе данных при каждом запросе.
Обратите внимание, что файл cookie сессии отправляется только при создании или изменении сессии. Если параметр SESSION_SAVE_EVERY_REQUEST имеет значение True, файл cookie сессии будет отправляться при каждом запросе.
Аналогичным образом, часть expires файла cookie сессии обновляется при каждой его отправке.
Сессия не сохраняется, если код состояния ответа равен 500.
Сессии на время работы браузера и постоянные сессии
С помощью параметра SESSION_EXPIRE_AT_BROWSER_CLOSE можно управлять тем, использует ли система сессий сессии на время работы браузера или постоянные сессии.
По умолчанию параметр SESSION_EXPIRE_AT_BROWSER_CLOSE имеет значение False, то есть файлы cookie сессий хранятся в браузерах пользователей в течение времени, заданного параметром SESSION_COOKIE_AGE. Используйте этот вариант, если не хотите, чтобы пользователям приходилось входить в систему при каждом запуске браузера.
Если параметр SESSION_EXPIRE_AT_BROWSER_CLOSE имеет значение True, Django будет использовать файлы cookie на время работы браузера — они истекают сразу после закрытия браузера пользователем. Используйте этот вариант, если хотите, чтобы пользователям приходилось входить в систему при каждом запуске браузера.
Этот параметр задаёт глобальное значение по умолчанию. Его можно переопределить для отдельной сессии, явно вызвав метод set_expiry() объекта request.session, как описано выше в разделе использование сессий в представлениях.
Примечание
Некоторые браузеры (например, Chrome) предоставляют настройки, позволяющие пользователям продолжать сеансы просмотра после закрытия и повторного открытия браузера. В некоторых случаях это может повлиять на параметр SESSION_EXPIRE_AT_BROWSER_CLOSE и помешать истечению срока действия сессий при закрытии браузера. Учитывайте это при тестировании приложений Django, в которых включён параметр SESSION_EXPIRE_AT_BROWSER_CLOSE.
Очистка хранилища сессий
По мере создания пользователями новых сессий на вашем сайте данные сессий могут накапливаться в хранилище. Если вы используете бэкенд базы данных, таблица базы данных django_session будет увеличиваться. Если вы используете файловый бэкенд, во временном каталоге будет накапливаться всё больше файлов.
Чтобы понять суть проблемы, рассмотрим работу бэкенда базы данных. Когда пользователь входит в систему, Django добавляет строку в таблицу базы данных django_session. Django обновляет эту строку при каждом изменении данных сессии. Если пользователь выходит из системы вручную, Django удаляет строку. Но если пользователь не выходит из системы, строка никогда не удаляется. Аналогичный процесс происходит и при использовании файлового бэкенда.
Django не выполняет автоматическую очистку просроченных сессий. Поэтому регулярно удалять просроченные сессии должны вы. Для этого Django предоставляет команду управления для очистки: clearsessions. Рекомендуется регулярно запускать эту команду, например ежедневно с помощью cron.
Обратите внимание, что бэкенд кэша не подвержен этой проблеме, поскольку кэши автоматически удаляют устаревшие данные. Бэкенд файлов cookie также не подвержен ей, поскольку данные сессии хранятся в браузерах пользователей.
Настройки
Некоторые настройки Django позволяют управлять поведением сессий:
Безопасность сессий
Поддомены сайта могут устанавливать файлы cookie на клиенте для всего домена. Это делает возможной фиксацию сессии, если разрешены файлы cookie от поддоменов, не контролируемых доверенными пользователями.
Например, злоумышленник может войти на good.example.com и получить действительную сессию для своей учётной записи. Если злоумышленник контролирует bad.example.com, он может использовать его, чтобы отправить вам свой ключ сессии, поскольку поддомену разрешено устанавливать файлы cookie для *.example.com. Когда вы посетите good.example.com, вы войдёте в систему как злоумышленник и можете случайно ввести свои конфиденциальные персональные данные (например, данные кредитной карты) в его учётную запись.
Другой возможный вариант атаки — если good.example.com установит для параметра SESSION_COOKIE_DOMAIN значение "example.com", из-за чего файлы cookie сессий с этого сайта будут отправляться на bad.example.com.
Технические подробности
- При использовании
JSONSerializerсловарь сессии принимает любые сериализуемые значенияjson. - Данные сессий хранятся в таблице базы данных с именем
django_session. - Django отправляет файл cookie, только если это необходимо. Если вы не зададите данные сессии, файл cookie сессии отправлен не будет.
Объект SessionStore
При внутренней работе с сессиями Django использует объект хранилища сессий из соответствующего движка сессий. По соглашению класс объекта хранилища сессий называется SessionStore и находится в модуле, указанном в параметре SESSION_ENGINE.
Все доступные в Django подклассы SessionStore реализуют следующие методы для работы с данными:
exists()create()save()delete()load()clear_expired()
Асинхронный интерфейс для этих методов предоставляется путём обёртывания их в sync_to_async(). Если доступна асинхронная реализация, методы можно реализовать напрямую:
aexists()acreate()asave()adelete()aload()aclear_expired()
Чтобы создать собственный движок сессий или настроить существующий, можно создать новый класс, унаследованный от SessionBase или любого другого существующего класса SessionStore.
Движки сессий можно расширять, однако расширение движков сессий на основе базы данных обычно требует дополнительных усилий (подробности см. в следующем разделе).
Расширение движков сессий на основе базы данных
Чтобы создать собственный движок сессий на основе базы данных, используя включённые в Django движки (а именно db и cached_db), можно унаследовать AbstractBaseSession и один из классов SessionStore.
AbstractBaseSession и BaseSessionManager можно импортировать из django.contrib.sessions.base_session, чтобы использовать их без добавления django.contrib.sessions в INSTALLED_APPS.
-
class base_session.AbstractBaseSession -
Абстрактная базовая модель сессии.
-
session_key -
Первичный ключ. Само поле может содержать до 40 символов. Текущая реализация создаёт строку из 32 символов (случайную последовательность цифр и строчных букв ASCII).
-
session_data -
Строка, содержащая закодированный и сериализованный словарь сессии.
-
expire_date -
Дата и время истечения срока действия сессии.
Просроченные сессии недоступны пользователю, однако могут по-прежнему храниться в базе данных до запуска команды управления
clearsessions.
-
classmethod get_session_store_class() -
Возвращает класс хранилища сессий, который будет использоваться с этой моделью сессии.
-
get_decoded() -
Возвращает декодированные данные сессии.
Декодирование выполняется классом хранилища сессий.
-
Диспетчер модели также можно настроить, создав подкласс BaseSessionManager:
-
class base_session.BaseSessionManager -
-
encode(session_dict) -
Возвращает переданный словарь сессии, сериализованный и закодированный в виде строки.
Кодирование выполняется классом хранилища сессий, связанным с классом модели.
-
save(session_key, session_dict, expire_date) -
Сохраняет данные сессии для указанного ключа сессии или удаляет сессию, если данные пусты.
-
Чтобы настроить классы SessionStore, переопределите методы и свойства, описанные ниже:
-
class backends.db.SessionStore -
Реализует хранилище сессий на основе базы данных.
-
classmethod get_model_class() -
Переопределите этот метод, чтобы вернуть собственную модель сессии, если она вам нужна.
-
create_model_instance(data) -
Возвращает новый экземпляр объекта модели сессии, представляющий текущее состояние сессии.
Переопределив этот метод, можно изменить данные модели сессии перед их сохранением в базе данных.
-
-
class backends.cached_db.SessionStore -
Реализует кэшируемое хранилище сессий на основе базы данных.
-
cache_key_prefix -
Префикс, добавляемый к ключу сессии для формирования строки ключа кэша.
-
Пример
В примере ниже показан собственный движок сессий на основе базы данных, который включает дополнительный столбец базы данных для хранения идентификатора учётной записи (что позволяет запрашивать в базе данных все активные сессии учётной записи):
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.contrib.sessions.base_session import AbstractBaseSession
from django.db import models
class CustomSession(AbstractBaseSession):
account_id = models.IntegerField(null=True, db_index=True)
@classmethod
def get_session_store_class(cls):
return SessionStore
class SessionStore(DBStore):
@classmethod
def get_model_class(cls):
return CustomSession
def create_model_instance(self, data):
obj = super().create_model_instance(data)
try:
account_id = int(data.get("_auth_user_id"))
except (ValueError, TypeError):
account_id = None
obj.account_id = account_id
return obj
При переходе со встроенного в Django хранилища сессий cached_db на собственное хранилище на основе cached_db следует переопределить префикс ключа кэша, чтобы избежать конфликта пространств имён:
class SessionStore(CachedDBStore):
cache_key_prefix = "mysessions.custom_cached_db_backend"
# ...
Идентификаторы сессий в URL-адресах
Система сессий Django полностью основана на файлах cookie. В отличие от PHP, она не использует идентификаторы сессий в URL-адресах в качестве крайней меры. Это намеренное проектное решение. Такое поведение не только делает URL-адреса некрасивыми, но и делает ваш сайт уязвимым к краже идентификаторов сессий через заголовок «Referer».
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/topics/http/sessions/