Spec-Zone.ru › Django 4.1

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

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

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

Сессии реализованы с помощью фрагмента средства промежуточного программного обеспечения.

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

  • Отредактируйте настройку MIDDLEWARE и убедитесь, что она содержит 'django.contrib.sessions.middleware.SessionMiddleware'. По умолчанию settings.py созданное django-admin startproject имеет SessionMiddleware включенными.

Если вы не хотите использовать сессии, удалите строку SessionMiddleware из MIDDLEWARE и 'django.contrib.sessions' из INSTALLED_APPS. Это сэкономит немного накладных расходов.

Настройка движка сессий

По умолчанию Django хранит сессии в вашей базе данных (используя модель django.contrib.sessions.models.Session). Хотя это удобно, в некоторых настройках быстрее хранить данные сессии в другом месте, поэтому Django можно настроить на хранение данных сессии на файловой системе или в кэше.

Использование сессий, поддерживаемых базой данных

Если вы хотите использовать сессии, поддерживаемые базой данных, добавьте 'django.contrib.sessions' в настройку INSTALLED_APPS.

После настройки установки запустите manage.py migrate для установки единственной таблицы базы данных, которая хранит данные сессии.

Использование кэшированных сессий

Для повышения производительности вы можете использовать кэшированное хранилище сессий.

Чтобы хранить данные сессий с помощью системы кэширования Django, необходимо сначала убедиться, что вы настроили свой кэш; подробности см. в документации по кэшу.

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

Вы должны использовать кэшированные сессии только если используете кэш Memcached или Redis. Кэш локальной памяти не удерживает данные достаточно долго, чтобы быть хорошим выбором, и быстрее использовать файловые или базовые сессии напрямую, вместо отправки всего через файловый или базовый кэш. Кроме того, кэш локальной памяти НЕ безопасен для нескольких процессов, поэтому, вероятно, не является хорошим выбором для производственной среды.

Если в CACHES определено несколько кэшей, Django будет использовать кэш по умолчанию. Чтобы использовать другой кэш, установите SESSION_CACHE_ALIAS в имя этого кэша.

После настройки кэша у вас есть два варианта хранения данных в кэше:

  • Установите 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`` или ``SECRET_KEY_FALLBACKS`` не являются секретными и вы используете django.contrib.sessions.serializers.PickleSerializer, это может привести к произвольному выполнению удаленного кода.

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

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

Данные сессии подписываются, но не шифруются

При использовании хранилища на основе файлов cookie клиент может прочитать данные сессии.

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

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

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

set_test_cookie()

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

test_cookie_worked()

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

delete_test_cookie()

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

get_session_cookie_age()

Возвращает значение настройки SESSION_COOKIE_AGE. Это можно переопределить в пользовательском бэкенде сессии.

set_expiry(value)

Устанавливает время истечения сессии. Вы можете передать различные значения:

  • Если value — целое число, сессия истечёт через указанное количество секунд бездействия. Например, вызов request.session.set_expiry(300) приведет к истечению сессии через 5 минут.
  • Если value — объект datetime или timedelta, сессия истечет в указанную дату/время.
  • Если value равно 0, cookie сессии пользователя истечёт при закрытии веб-браузера пользователя.
  • Если value равно None, сессия возвращается к использованию глобальной политики истечения сессии.

Чтение сессии не считается активностью для целей истечения. Истечение сессии вычисляется с последнего момента изменения сессии.

get_expiry_age()

Возвращает количество секунд до истечения срока действия этой сессии. Для сессий без пользовательского срока действия (или тех, которые установлены на истечение при закрытии браузера), это будет равно SESSION_COOKIE_AGE.

Эта функция принимает два необязательных ключевых аргумента:

  • modification: последнее изменение сессии, как объект datetime. По умолчанию — текущее время.
  • expiry: информация об истечении срока действия сессии, как объект datetime, целое число (в секундах) или None. По умолчанию — значение, хранящееся в сессии set_expiry(), если таковое имеется, или None.

Примечание

Этот метод используется бэкендами сессий для определения срока действия сессии в секундах при сохранении сессии. Он на самом деле не предназначен для использования вне этого контекста.

В частности, хотя возможно определить оставшийся срок действия сессии только когда у вас есть правильное значение modification и expiry установлено как объект datetime, где у вас есть значение modification, проще вручную вычислить срок действия:

expires_at = modification + timedelta(seconds=settings.SESSION_COOKIE_AGE)
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 (или любой ключ из SECRET_KEY_FALLBACKS) известен злоумышленнику (нет встроенной уязвимости в 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 или любой ключ из SECRET_KEY_FALLBACKS станет известен злоумышленнику.

Устарело начиная с версии 4.1: Из-за риска удалённого исполнения кода этот сериализатор устарел и будет удалён в Django 5.0.

Написание собственного сериализатора

Обратите внимание, что 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.check_password(request.POST['password']):
        request.session['member_id'] = m.id
        return HttpResponse("You're logged in.")
    else:
        return HttpResponse("Your username and password didn't match.")

…И этот вид выполняет выход члена, согласно login() выше:

def logout(request):
    try:
        del request.session['member_id']
    except KeyError:
        pass
    return HttpResponse("You're logged out.")

Стандартная функция django.contrib.auth.logout() на самом деле делает немного больше, чем это, чтобы предотвратить непреднамеренную утечку данных. Она вызывает метод flush() объекта request.session. Мы используем этот пример в качестве демонстрации того, как работать с объектами сессии, а не как полную logout() реализацию.

Установка тестовых файлов 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 позволяют вам управлять поведением сессий:

  • 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.
  • Данные сессии хранятся в таблице базы данных, названной 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

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

Spec-Zone.ru

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