Как использовать сеансы ¶
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 ¶
Чтобы использовать сеансы на основе файлов cookie, установите для SESSION_ENGINE
параметра значение
"django.contrib.sessions.backends.signed_cookies"
. Данные сеанса будут храниться с использованием инструментов Django для криптографической подписи
и SECRET_KEY
настройки.
Примечание
Рекомендуется оставить этот SESSION_COOKIE_HTTPONLY
параметр включенным, True
чтобы предотвратить доступ к сохраненным данным из JavaScript.
Предупреждение
Если SECRET_KEY не хранится в секрете и вы используете
PickleSerializer
, это может привести к произвольному удаленному выполнению кода.
Злоумышленник, владеющий им, SECRET_KEY
может не только сгенерировать фальсифицированные данные сеанса, которым будет доверять ваш сайт, но и удаленно выполнить произвольный код, поскольку данные сериализуются с помощью pickle.
Если вы используете сеансы на основе файлов cookie, обратите особое внимание на то, чтобы ваш секретный ключ всегда был полностью секретным для любой системы, которая может быть доступна удаленно.
Данные сеанса подписаны, но не зашифрованы
При использовании бэкэнда cookie данные сеанса могут быть прочитаны клиентом.
MAC (код аутентификации сообщения) используется для защиты данных от изменений со стороны клиента, так что данные сеанса будут признаны недействительными при подделке. Такое же признание недействительности происходит, если клиент, хранящий файл cookie (например, браузер вашего пользователя), не может сохранить все файлы cookie сеанса и отбрасывает данные. Несмотря на то, что Django сжимает данные, все же возможно превыситьобщий лимит 4096 байт на файл cookie.
Нет гарантии свежести
Также обратите внимание, что хотя MAC может гарантировать подлинность данных (что они были сгенерированы вашим сайтом, а не кем-то другим) и целостность данных (все они есть и правильные), он не может гарантировать актуальность, т.е. вам отправляют обратно последнее, что вы отправили клиенту. Это означает, что для некоторых видов использования данных сеанса серверная часть cookie может открыть вас для атак повторного воспроизведения . В отличие от других бэкэндов сеансов, которые хранят запись каждого сеанса на стороне сервера и аннулируют его, когда пользователь выходит из системы, сеансы на основе файлов cookie не аннулируются, когда пользователь выходит из системы. Таким образом, если злоумышленник крадет файл cookie пользователя, он может использовать этот файл cookie для входа в систему от имени этого пользователя, даже если пользователь выйдет из системы. Файлы cookie будут определены как «устаревшие» только в том случае, если они старше вашего
SESSION_COOKIE_AGE
.
Представление
Наконец, размер файла cookie может повлиять на скорость вашего сайта.
Использование сессий в представлениях ¶
Когда SessionMiddleware
он активирован, каждый HttpRequest
объект - первый аргумент любой функции просмотра Django - будет иметь
session
атрибут, который является объектом, подобным словарю.
Вы можете читать и писать request.session
в любой момент, на ваш взгляд. Вы можете редактировать его несколько раз.
-
класс
backends.base.
SessionBase
¶ Это базовый класс для всех объектов сеанса. Он имеет следующие стандартные словарные методы:
-
__getitem__
( ключ ) ¶ Пример:
fav_color = request.session['fav_color']
-
__setitem__
( ключ , значение ) ¶ Пример:
request.session['fav_color'] = 'blue'
-
__delitem__
( ключ ) ¶ Пример: . Это возникает, если данный еще не находится в сеансе.
del request.session['fav_color']
KeyError
key
-
__contains__
( ключ ) ¶ Пример:
'fav_color' in request.session
-
get
( ключ , по умолчанию = Нет ) ¶ Пример:
fav_color = request.session.get('fav_color', 'red')
-
pop
( ключ , по умолчанию = __ not_given ) ¶ Пример:
fav_color = request.session.pop('fav_color', 'blue')
-
keys
() ¶
-
items
() ¶
-
setdefault
() ¶
-
clear
() ¶
В нем также есть следующие методы:
-
flush
() ¶ Удаляет данные текущего сеанса из сеанса и удаляет файл cookie сеанса. Это используется, если вы хотите убедиться, что данные предыдущего сеанса не могут быть снова доступны из браузера пользователя (например,
django.contrib.auth.logout()
функция вызывает его).
Устанавливает тестовый файл cookie, чтобы определить, поддерживает ли браузер пользователя файлы cookie. Из-за того, как работают файлы cookie, вы не сможете проверить это до следующего запроса страницы. См. Раздел « Настройка тестовых файлов cookie» ниже для получения дополнительной информации.
Возвращает либо
True
илиFalse
, в зависимости от того, принял ли браузер пользователя тестовый файл cookie. Из-за того, как работают файлы cookie, вам придется вызыватьset_test_cookie()
предыдущий отдельный запрос страницы. См. Раздел « Настройка тестовых файлов cookie» ниже для получения дополнительной информации.
Удаляет тестовый файл cookie. Используйте это, чтобы убрать за собой.
Возвращает возраст файлов cookie сеанса в секундах. По умолчанию
SESSION_COOKIE_AGE
.
-
set_expiry
( значение ) ¶ Устанавливает время окончания сеанса. Вы можете передать несколько разных значений:
- Если
value
это целое число, сеанс истечет после этого количества секунд бездействия. Например, при вызовеrequest.session.set_expiry(300)
сеанс истечет через 5 минут. - Если
value
это объектdatetime
илиtimedelta
, сеанс истечет в указанную дату / время. Обратите внимание , чтоdatetime
иtimedelta
значение только сериализации , если вы используетеPickleSerializer
. - Если
value
есть0
, куки сессии пользователя истекает , когда веб - браузер пользователя закрыт. - Если
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
для сериализации данных сеанса. Если вы используете бэкэнд сеанса подписанных файлов cookie и SECRET_KEY
известен злоумышленнику (в Django нет внутренней уязвимости, которая могла бы вызвать утечку), злоумышленник может вставить строку в свой сеанс, которая, если ее не выбрать, выполняет произвольную код на сервере. Техника для этого проста и легко доступна в Интернете. Хотя хранилище сеанса cookie подписывает данные, хранящиеся в cookie, для предотвращения взлома, SECRET_KEY
утечка немедленно перерастает в уязвимость удаленного выполнения кода.
Связанные сериализаторы ¶
-
класс
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, например байты, отличные от UTF8, такие как
'\xd9'
(который увеличиваетсяUnicodeDecodeError
), не могут быть сохранены.Дополнительные сведения об ограничениях сериализации JSON см. В разделе « Создание собственного сериализатора ».
-
класс
serializers.
PickleSerializer
¶ Поддерживает произвольные объекты Python, но, как описано выше, может привести к уязвимости удаленного выполнения кода, если
SECRET_KEY
станет известно злоумышленнику.
Напишите свой собственный сериализатор ¶
Обратите внимание, что, в отличие от PickleSerializer
, он JSONSerializer
не может обрабатывать произвольные типы данных Python. Как это часто бывает, приходится искать компромисс между удобством и безопасностью. Если вы хотите сохранить более продвинутые тип данных , в том числе datetime
и Decimal
в формате JSON при поддержке сеансов, вам нужно будет написать собственный сериалайзер (или преобразовать такие значения сериализуемого объекта JSON перед их сохранением в request.session
). Хотя сериализация этих значений часто проста ( DjangoJSONEncoder
может быть полезна), написание декодера, который может надежно вернуть то же самое, что вы вставили, более хрупко. Например, вы рискуете вернуть a, datetime
который на самом деле был строкой, которая случайно оказалась в том же формате, который был выбран для
datetime
s).
В вашем классе сериализатора должны быть реализованы два метода
и, соответственно , для сериализации и десериализации словаря данных сеанса.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()
реализацию.
Настройка тестовых файлов cookie ¶
Для удобства Django предоставляет способ проверить, принимает ли браузер пользователя файлы cookie. Вызов set_test_cookie()
метода request.session
в представлении и вызов
test_cookie_worked()
в следующем представлении - не в том же вызове представления.
Это неудобное разделение между set_test_cookie()
и test_cookie_worked()
необходимо из-за того, как работают файлы cookie. Когда вы устанавливаете файл cookie, вы не можете определить, принял ли его браузер, до следующего запроса браузера.
Это хорошая практика,
delete_test_cookie()
чтобы убирать за собой. Сделайте это после того, как убедитесь, что тестовый файл 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 будет сохранять сеанс в базе данных при каждом запросе.
Обратите внимание, что файл cookie сеанса отправляется только после создания или изменения сеанса. Если SESSION_SAVE_EVERY_REQUEST
есть True
, cookie сеанса будет отправляться при каждом запросе.
Точно так же expires
часть файла cookie сеанса обновляется каждый раз при отправке файла 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 длины браузера - файлы 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.
Обратите внимание, что серверная часть кеша не подвержена этой проблеме, поскольку кеши автоматически удаляют устаревшие данные. Бэкэнд тоже не работает, потому что данные сеанса хранятся в браузерах пользователей.
Настройки ¶
Несколько настроек 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
.
Технические детали ¶
- Словарь сеанса принимает любое
json
сериализуемое значение при использованииJSONSerializer
или любой выбираемый объект Python при использованииPickleSerializer
. См.pickle
Модуль для получения дополнительной информации. - Данные сеанса хранятся в таблице базы данных с именем
django_session
. - Django отправляет cookie только в случае необходимости. Если вы не установите какие-либо данные сеанса, он не будет отправлять файл cookie сеанса.
SessionStore
Объект ¶
При внутренней работе с сеансами 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
.
-
класс
base_session.
AbstractBaseSession
¶ Абстрактная базовая модель сеанса.
-
session_key
¶ Первичный ключ. Само поле может содержать до 40 символов. Текущая реализация генерирует строку из 32 символов (случайная последовательность цифр и строчных букв ASCII).
-
session_data
¶ Строка, содержащая закодированный и сериализованный словарь сеанса.
-
expire_date
¶ Дата и время, указывающее, когда истекает срок сеанса.
Просроченные сеансы недоступны для пользователя, однако они все еще могут храниться в базе данных до тех пор, пока не
clearsessions
будет запущена команда управления.
-
classmethod
get_session_store_class
() ¶ Возвращает класс хранилища сеанса, который будет использоваться с этой моделью сеанса.
-
get_decoded
() ¶ Возвращает декодированные данные сеанса.
Декодирование выполняется классом хранилища сеансов.
-
Вы также можете настроить диспетчер моделей, создав подклассы
BaseSessionManager
:
-
класс
base_session.
BaseSessionManager
¶ -
encode
( session_dict ) ¶ Возвращает указанный словарь сеанса, сериализованный и закодированный в виде строки.
Кодирование выполняется классом хранилища сеансов, привязанным к классу модели.
-
save
( session_key , session_dict , expire_date ) ¶ Сохраняет данные сеанса для предоставленного сеансового ключа или удаляет сеанс, если данные пусты.
-
Настройка SessionStore
классов достигается путем переопределения методов и свойств, описанных ниже:
-
класс
backends.db.
SessionStore
¶ Реализует хранилище сеансов на основе базы данных.
-
classmethod
get_model_class
() ¶ Переопределите этот метод, чтобы он возвращал настраиваемую модель сеанса, если она вам нужна.
-
create_model_instance
( данные ) ¶ Возвращает новый экземпляр объекта модели сеанса, который представляет текущее состояние сеанса.
Переопределение этого метода дает возможность изменять данные модели сеанса перед их сохранением в базе данных.
-
classmethod
-
класс
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
Если вы переходите из встроенного cached_db
хранилища сеансов Django в пользовательское хранилище на основе cached_db
, вам следует переопределить префикс ключа кеша, чтобы предотвратить конфликт пространств имен:
class SessionStore(CachedDBStore):
cache_key_prefix = 'mysessions.custom_cached_db_backend'
# ...
Идентификаторы сеанса в URL ¶
Фреймворк сеансов Django полностью и исключительно основан на файлах cookie. Он не прибегает к добавлению идентификаторов сеансов в URL-адреса в крайнем случае, как это делает PHP. Это намеренное дизайнерское решение. Такое поведение не только делает URL-адреса уродливыми, но и делает ваш сайт уязвимым для кражи идентификатора сеанса через заголовок «Referer».