Spec-Zone.ru › Django 4.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 (код аутентификации сообщения) для защиты данных от изменений клиентом, так что данные сессии будут считаться недействительными при попытке их подделки. Такое же недействительное состояние произойдёт, если клиент, хранящий cookie (например, браузер вашего пользователя), не может сохранить весь куки-файл сессии и потеряет данные. Даже если Django сжимает данные, всё же вполне возможно превысить общее ограничение в 4096 байт на cookie.

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

Обратите также внимание, что, хотя MAC может гарантировать аутентичность данных (что они были сгенерированы вашим сайтом, а не кем-то другим), и целостность данных (что они все на месте и корректны), он не может гарантировать свежесть, т.е. что вам отправляется последняя отправленная клиенту информация. Это означает, что для некоторых способов использования данных сессии бэкенд куки-файлов может открыть вас для атак с повторением. В отличие от других бэкендов сессий, которые хранят на стороне сервера записи каждой сессии и делают их недействительными при выходе пользователя, сессии на основе куки-файлов не аннулируются при выходе пользователя. Таким образом, если злоумышленник украдёт куки-файл пользователя, он может использовать этот куки-файл для входа как этот пользователь, даже если пользователь вышел. Куки-файлы будут считаться «просроченными» только если они старше, чем ваш 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() вызывает её).

set_test_cookie()

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

test_cookie_worked()

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

delete_test_cookie()

Удаляет тестовое cookie. Используйте это для очистки.

get_session_cookie_age()

Возвращает срок действия cookie сессии в секундах. По умолчанию SESSION_COOKIE_AGE.

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

Установка тестовых файлов 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.

Обратите внимание, что кеш-бэкенд не подвержен этой проблеме, потому что кэши автоматически удаляют устаревшие данные. То же самое относится и к бэкенду файлов cookie, поскольку данные сессии хранятся браузерами пользователей.

Настройки

Несколько Настроек Django позволяют управлять поведением сессий:

  • SESSION_CACHE_ALIAS
  • SESSION_COOKIE_AGE
  • SESSION_COOKIE_DOMAIN
  • SESSION_COOKIE_HTTPONLY
  • SESSION_COOKIE_NAME
  • SESSION_COOKIE_PATH
  • SESSION_COOKIE_SAMESITE
  • 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 символов (случайная последовательность цифр и строчных 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

Если вы мигрируете из встроенного cached_db хранилища сессий 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/4.0/topics/http/sessions/

Spec-Zone.ru

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