Как использовать сессии
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. Кэш-бекенд локальной памяти не сохраняет данные достаточно долго, чтобы быть хорошим выбором, и будет быстрее использовать файловые или базовые сессии напрямую вместо отправки всего через файловый или баз данных кэши. Кроме того, кэш-бекенд локальной памяти НЕ безопасен для многопроцессных систем, поэтому, вероятно, не подходит для производственной среды.
Если у вас определено несколько кэшей в CACHES, Django будет использовать кэш по умолчанию. Чтобы использовать другой кэш, установите SESSION_CACHE_ALIAS на имя этого кэша.
После настройки кэша у вас есть два варианта хранения данных в кэше:
- Установите
SESSION_ENGINEна"django.contrib.sessions.backends.cache"для простого кэширования сессий. Данные сессии будут храниться непосредственно в вашем кэше. Однако данные сессии могут не сохраняться: кэшированные данные могут быть удалены, если кэш заполнится или если сервер кэша перезапустится. - Для сохранения кэшированных данных установите
SESSION_ENGINEна"django.contrib.sessions.backends.cached_db". Это использует кэш с записью через – каждая запись в кэш также запишется в базу данных. Чтение сессий использует базу данных только в том случае, если данные еще не в кэше.
Оба хранилища сессий достаточно быстрые, но простое хранилище быстрее, потому что оно не учитывает сохранение. В большинстве случаев бекенд cached_db будет достаточно быстрым, но если вам нужна последняя производительность, и вы готовы время от времени удалять данные сессий, бекенд cache для вас.
Если вы используете бекенд сессий cached_db, вам также необходимо следовать инструкциям по настройке для использования сессий с поддержкой базы данных.
Использование сессий на основе файлов
Чтобы использовать сессии на основе файлов, установите настройку SESSION_ENGINE на "django.contrib.sessions.backends.file".
Вы также можете установить настройку SESSION_FILE_PATH (по умолчанию значение, полученное из tempfile.gettempdir(), вероятно, /tmp ), чтобы управлять тем, где Django хранит файлы сессий. Убедитесь, что ваш веб-сервер имеет разрешения на чтение и запись в этом расположении.
Использование сессий на основе файлов cookie
Примечание
Рекомендуется оставить настройку SESSION_COOKIE_HTTPONLY на значении True для предотвращения доступа к сохранённым данным из JavaScript.
Предупреждение
Если SECRET_KEY не является секретным, и вы используете PickleSerializer, это может привести к произвольному удаленному выполнению кода.
Злоумышленник, владеющий SECRET_KEY, не только может генерировать поддельные данные сессии, которым ваш сайт будет доверять, но и удалённо выполнить произвольный код, так как данные сериализуются с помощью pickle.
Если вы используете сессии на основе файлов cookie, уделите особое внимание тому, чтобы ваш секретный ключ всегда хранился в полной секретности для любых систем, которые могут быть удалённо доступны.
Данные сессии подписаны, но не зашифрованы
При использовании куки-бекенда клиент может прочитать данные сессии.
MAC (Message Authentication Code) используется для защиты данных от изменений клиентом, так что данные сессии будут аннулированы при внесении изменений. Такое же аннулирование происходит, если клиент, хранящий куки (например, браузер вашего пользователя), не может сохранить все данные куки сессии и теряет данные. Несмотря на то, что Django сжимает данные, вполне возможно превысить обычное ограничение в 4096 байт на файл cookie.
Гарантии свежести нет
Обратите также внимание, что, хотя MAC может гарантировать подлинность данных (что они были сгенерированы вашим сайтом, а не кем-то другим) и целостность данных (что они все там и правильные), он не может гарантировать свежесть, то есть, что вам отправляется последняя версия отправленной клиенту информации. Это означает, что для некоторых применений данных сессий бекенд куки может подвергнуть вас атакам повтора. В отличие от других бекендов сессий, которые ведут запись каждой сессии на стороне сервера и аннулируют ее при выходе пользователя из системы, сессии на основе файлов cookie не аннулируются при выходе пользователя. Таким образом, если злоумышленник похищает куки пользователя, он может использовать эти куки для входа как этот пользователь, даже если пользователь вышел из системы. Файлы cookie будут считаться устаревшими только если они старше, чем ваш SESSION_COOKIE_AGE.
Производительность
Наконец, размер файла cookie может повлиять на скорость вашего сайта.
Использование сессий в представлениях
Когда 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']. Это вызываетKeyError, если заданныйkeyеще не содержится в сессии.
-
__contains__(key) -
Пример:
'fav_color' in request.session
-
get(key, default=None) -
Пример:
fav_color = request.session.get('fav_color', 'red')
-
pop(key, default=__not_given) -
Пример:
fav_color = request.session.pop('fav_color', 'blue')
-
keys()
-
items()
-
setdefault()
-
clear()
Также у него есть эти методы:
-
flush() -
Удаляет текущие данные сессии из сессии и удаляет cookie сессии. Используется, если вы хотите гарантировать, что к предыдущим данным сессии больше нельзя получить доступ из браузера пользователя (например, функция
django.contrib.auth.logout()вызывает её).
-
Устанавливает тестовый cookie для определения того, поддерживает ли браузер пользователя cookies. Из-за того, как работают cookies, вы не сможете протестировать это до следующего запроса на страницу пользователя. Подробнее см. Настройка тестовых cookies ниже.
-
Возвращает либо
True, либоFalse, в зависимости от того, принял ли браузер пользователя тестовый cookie. Из-за того, как работают cookies, вам нужно будет вызватьset_test_cookie()в предыдущем, отдельном запросе на страницу. Подробнее см. Настройка тестовых cookies ниже.
-
Удаляет тестовый cookie. Используйте это, чтобы очистить после себя.
-
set_expiry(value) -
Устанавливает время истечения сессии. Вы можете передать различные значения:
- Если
value— целое число, сессия истечёт по прошествии указанного количества секунд бездействия. Например, вызовrequest.session.set_expiry(300)заставит сессию истечь через 5 минут. - Если
value— объектdatetimeилиtimedelta, сессия истечёт в указанную дату/время. Обратите внимание, что значенияdatetimeиtimedeltaсериализуются только при использованииPickleSerializer. - Если
valueравно0, cookie сессии пользователя истечёт при закрытии веб-браузера пользователя. - Если
valueравноNone, сессия возвращается к использованию глобальной политики истечения сессии.
Чтение сессии не считается активностью для целей истечения. Истечение сессии вычисляется по последнему времени изменения сессии.
- Если
-
get_expiry_age() -
Возвращает количество секунд до истечения срока действия этой сессии. Для сессий без пользовательского истечения срока действия (или тех, которые установлены на истечение при закрытии браузера), это будет равно
SESSION_COOKIE_AGE.Эта функция принимает два необязательных ключевых аргумента:
-
modification: последнее изменение сессии, как объектdatetime. По умолчанию — текущее время. -
expiry: сведения об истечении срока действия сессии, как объектdatetime, числоint(в секундах), илиNone. По умолчанию — значение, хранящееся в сессии методомset_expiry(), если он есть, илиNone.
-
-
get_expiry_date() -
Возвращает дату истечения срока действия этой сессии. Для сессий без пользовательского истечения срока действия (или тех, которые установлены на истечение при закрытии браузера), это будет равно дате через
SESSION_COOKIE_AGEсекунд от текущего момента.Эта функция принимает те же ключевые аргументы, что и
get_expiry_age().
-
get_expire_at_browser_close() -
Возвращает либо
True, либоFalse, в зависимости от того, истечёт ли cookie сессии пользователя при закрытии веб-браузера пользователя.
-
clear_expired() -
Удаляет истекшие сессии из хранилища сессий. Этот класс-метод вызывается методом
clearsessions.
-
cycle_key() -
Создаёт новый ключ сессии, сохраняя при этом текущие данные сессии.
django.contrib.auth.login()вызывает этот метод, чтобы снизить риск фиксации сессии.
-
Сериализация сессии
По умолчанию Django сериализует данные сессии с помощью JSON. Вы можете использовать настройку SESSION_SERIALIZER для настройки формата сериализации сессии. Даже с оговорками, описанными в Напишите свой сериализатор, мы настоятельно рекомендуем использовать сериализацию JSON, особенно если вы используете хранилище cookie.
Например, вот сценарий атаки, если вы используете pickle для сериализации данных сессии. Если вы используете хранилище signed cookie сессии и SECRET_KEY известен злоумышленнику (нет встроенной уязвимости в Django, которая бы вызвала утечку), злоумышленник мог бы вставить строку в свою сессию, которая, при распаковке, выполнит произвольный код на сервере. Техника для этого проста и легко доступна в интернете. Хотя хранилище cookie сессии подписывает хранящиеся в 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.
-
class serializers.PickleSerializer -
Поддерживает произвольные объекты Python, но, как описано выше, может привести к уязвимости удалённого выполнения кода, если
SECRET_KEYстанет известен злоумышленнику.
Напишите свой сериализатор
Обратите внимание, что в отличие от PickleSerializer, JSONSerializer не может обрабатывать произвольные типы данных Python. Как часто бывает, существует компромисс между удобством и безопасностью. Если вы хотите хранить более сложные типы данных, включая datetime и Decimal в сессиях, основанных на JSON, вам необходимо написать собственный сериализатор (или преобразовать такие значения в сериализуемое в 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.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() реализацию.
Установка тестовых куки
Эта неловкая разделение между set_test_cookie() и test_cookie_worked() необходимо из-за работы куки. Когда вы устанавливаете куки, вы не можете определить, принял ли браузер её, пока браузер не сделает следующий запрос.
Хорошей практикой является использование delete_test_cookie() для очистки за собой. Сделайте это после того, как вы убедились, что тестовые куки сработали.
Вот типичный пример использования:
from django.http import HttpResponse
from django.shortcuts import render
def login(request):
if request.method == 'POST':
if request.session.test_cookie_worked():
request.session.delete_test_cookie()
return HttpResponse("You're logged in.")
else:
return HttpResponse("Please enable cookies and try again.")
request.session.set_test_cookie()
return render(request, 'foo/login_form.html')
Использование сессий вне представлений
Примечание
Примеры в этом разделе импортируют объект 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 будет сохранять сессию в базе данных на каждом запросе.
Обратите внимание, что куки сессии отправляются только тогда, когда сессия была создана или изменена. Если SESSION_SAVE_EVERY_REQUEST имеет значение True, куки сессии будут отправляться при каждом запросе.
Аналогично, часть expires куки сессии обновляется каждый раз, когда куки сессии отправляется.
Сессия не сохраняется, если код состояния ответа равен 500.
Сессии на время браузера против постоянных сессий
Вы можете контролировать, использует ли система сессий сессии на время браузера или постоянные сессии, с помощью настройки SESSION_EXPIRE_AT_BROWSER_CLOSE.
По умолчанию SESSION_EXPIRE_AT_BROWSER_CLOSE установлено в значение False, что означает, что куки сессии будут храниться в браузере пользователя до тех пор, пока не истечет срок действия SESSION_COOKIE_AGE. Используйте эту настройку, если вы не хотите, чтобы пользователи каждый раз должны были входить в систему при открытии браузера.
Если SESSION_EXPIRE_AT_BROWSER_CLOSE установлено в значение True, Django будет использовать куки на время браузера — куки, которые истекают, как только пользователь закроет браузер. Используйте эту настройку, если вы хотите, чтобы пользователи каждый раз должны были входить в систему при открытии браузера.
Эта настройка является глобальным значением по умолчанию и может быть переопределена на уровне каждой сессии, явно вызвав метод 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.
Обратите внимание, что кэш-бэкэнд не уязвим для этой проблемы, так как кеши автоматически удаляют устаревшие данные. То же касается и бэкэнда куки, так как данные сессии хранятся в браузерах пользователей.
Настройки
Несколько настроек Django дают вам контроль над поведением сессий:
SESSION_CACHE_ALIASSESSION_COOKIE_AGESESSION_COOKIE_DOMAINSESSION_COOKIE_HTTPONLYSESSION_COOKIE_NAMESESSION_COOKIE_PATHSESSION_COOKIE_SAMESITESESSION_COOKIE_SECURESESSION_ENGINESESSION_EXPIRE_AT_BROWSER_CLOSESESSION_FILE_PATHSESSION_SAVE_EVERY_REQUESTSESSION_SERIALIZER
Безопасность сессий
Поддомены на сайте могут устанавливать куки на клиенте для всего домена. Это делает возможной фиксацию сессии, если куки разрешены для поддоменов, не контролируемых надёжными пользователями.
Например, злоумышленник может войти в good.example.com и получить действительную сессию для своей учётной записи. Если злоумышленник контролирует bad.example.com, он может использовать его для отправки ключа сессии вам, так как поддомен разрешено устанавливать куки на *.example.com. Когда вы посещаете good.example.com, вы будете войти как злоумышленник и можете случайно ввести ваши конфиденциальные личные данные (например, данные кредитной карты) в учётную запись злоумышленника.
Ещё одна возможная атака произойдёт, если good.example.com установит свой SESSION_COOKIE_DOMAIN на "example.com", что вызовет отправку куков сессии с этого сайта на bad.example.com.
Технические детали
- Словарь сессии принимает любое
jsonсериализуемое значение при использованииJSONSerializerили любой пиклируемый Python объект при использованииPickleSerializer. Смотрите модульpickleдля получения дополнительной информации. - Данные сессии хранятся в таблице базы данных с именем
django_session. - Django отправляет куки только в случае необходимости. Если вы не задаёте данные сессии, куки сессии не будут отправлены.
Объект хранилища сессий
При работе с сессиями внутри Django используется объект хранилища сессии из соответствующего движка сессий. По соглашению, класс объекта хранилища сессий называется SessionStore и расположен в модуле, указанном в SESSION_ENGINE.
Все классы SessionStore Django наследуются от SessionBase и реализуют методы обработки данных, а именно:
exists()create()save()delete()load()clear_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 для сессий полностью и исключительно основан на куках. Он не переходит к размещению идентификаторов сессий в URL-адресах в качестве крайней меры, как это делает PHP. Это преднамеренное конструкторское решение. Такое поведение не только ухудшает вид URL-адресов, но и делает ваш сайт уязвимым для кражи идентификаторов сессий через заголовок «Referer».
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/2.1/topics/http/sessions/