Spec-Zone.ru › Django 2.0

Как использовать сессии

Django предоставляет полную поддержку анонимных сессий. Система сессий позволяет хранить и извлекать произвольные данные для каждого посетителя сайта. Данные хранятся на стороне сервера, а отправка и получение куки-файлов абстрагированы. Куки-файлы содержат идентификатор сессии — а не сами данные (если вы не используете бекенд на основе куки).

Включение сессий

Сессии реализуются посредством модуля средств-посредников.

Для включения функциональности сессий выполните следующие действия:

  • Отредактируйте настройку 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 сохраняет файлы сессий. Убедитесь, что ваш веб-сервер имеет разрешения на чтение и запись в этом месте.

Использование сессий на основе куки

Чтобы использовать сессии на основе куки, установите настройку SESSION_ENGINE на "django.contrib.sessions.backends.signed_cookies". Данные сессий будут храниться с использованием инструментов Django для криптографического шифрования и настройки SECRET_KEY.

Примечание

Рекомендуется оставлять настройку SESSION_COOKIE_HTTPONLY в значении True для предотвращения доступа к хранимым данным из JavaScript.

Предупреждение

Если ключ SECRET_KEY не является секретным, и вы используете PickleSerializer, это может привести к произвольному выполнению удаленного кода.

Злоумышленник, обладающий ключом SECRET_KEY, может не только генерировать поддельные данные сессии, которым доверяет ваш сайт, но и удалённо выполнить произвольный код, так как данные сериализуются с помощью pickle.

Если вы используете сессии на основе куки, особое внимание уделите тому, чтобы ваш секретный ключ всегда хранился в секрете, для любой системы, которая может быть удалённо доступна.

Данные сессии подписаны, но не зашифрованы

При использовании бэкенда куки клиент может прочитать данные сессии.

Для защиты данных от изменений клиентом используется MAC (Message Authentication Code), поэтому данные сессии будут аннулированы при попытке их изменения. Такое же аннулирование происходит, если клиент, хранящий куки (например, браузер вашего пользователя), не может сохранить все данные куки и теряет информацию. Несмотря на то, что Django сжимает данные, вполне возможно превысить стандартное ограничение в 4096 байт на куки.

Гарантии свежести нет

Обратите также внимание, что, хотя MAC может гарантировать подлинность данных (что они были сгенерированы вашим сайтом, а не кем-то другим) и целостность данных (что они все там и правильные), он не может гарантировать свежесть, то есть что вам возвращается последняя информация, отправленная клиенту. Это означает, что при некоторых применениях данных сессии бэкенд куки может открыть вас для атак повторения. В отличие от других бэкендов сессий, которые ведут серверную запись каждой сессии и делают её недействительной, когда пользователь выходит из системы, сессии на основе куки не аннулируются при выходе пользователя. Следовательно, если злоумышленник украдёт куки пользователя, он может войти как этот пользователь, даже если пользователь вышел из системы. Куки будут считаться «просроченными» только если они старше, чем SESSION_COOKIE_AGE.

Производительность

Наконец, размер куки может повлиять на скорость вашего сайта.

Использование сессий в представлениях

Когда 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() вызывает её).

set_test_cookie()

Устанавливает тестовый cookie для определения, поддерживает ли браузер пользователя cookies. Из-за того, как работают cookies, вы не сможете протестировать это, пока пользователь не обратится к следующей странице. Более подробная информация о настройке тестовых cookies ниже в разделе Настройка тестовых cookies.

test_cookie_worked()

Возвращает либо True или False, в зависимости от того, принял ли браузер пользователя тестовый cookie. Из-за того, как работают cookies, вам необходимо вызвать set_test_cookie() на предыдущем, отдельном запросе страницы. Более подробная информация о настройке тестовых cookies ниже в разделе Настройка тестовых cookies.

delete_test_cookie()

Удаляет тестовый 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, целого числа (в секундах) или 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 сразу же превращается в уязвимость удалённого выполнения кода.

Встроенные сериализаторы

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() реализацию.

Установка тестовых куки

Для удобства Django предоставляет лёгкий способ проверки того, принимает ли браузер пользователя куки. Просто вызовите метод set_test_cookie() объекта request.session в представлении и вызовите test_cookie_worked() в последующем представлении – не в том же вызове представления.

Эта неуклюжая разделение между 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_ALIAS
  • SESSION_COOKIE_AGE
  • SESSION_COOKIE_DOMAIN
  • SESSION_COOKIE_HTTPONLY
  • SESSION_COOKIE_NAME
  • SESSION_COOKIE_PATH
  • SESSION_COOKIE_SECURE
  • SESSION_ENGINE
  • SESSION_EXPIRE_AT_BROWSER_CLOSE
  • SESSION_FILE_PATH
  • SESSION_SAVE_EVERY_REQUEST
  • SESSION_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 отправляет куки только в случае необходимости. Если вы не устанавливаете данные сессии, куки сессии не будут отправлены.

Объект 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.

class base_session.AbstractBaseSession

Абстрактная базовая модель сессии.

session_key

Первичный ключ. Сам поле может содержать до 40 символов. Текущая реализация генерирует строку из 32 символов (случайная последовательность цифр и строчных латинских букв).

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, вы должны переопределить префикс ключа кэша, чтобы избежать конфликтов имён:

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.0/topics/http/sessions/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API