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

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

Включение сеансов

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

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

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

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

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

Когда 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']KeyErrorkey

__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который на самом деле был строкой, которая случайно оказалась в том же формате, который был выбран для datetimes).

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

Чтобы создать собственный механизм сеанса или настроить существующий, вы можете создать новый класс, наследующий от 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будет запущена команда управления.

classmethodget_session_store_class ()

Возвращает класс хранилища сеанса, который будет использоваться с этой моделью сеанса.

get_decoded()

Возвращает декодированные данные сеанса.

Декодирование выполняется классом хранилища сеансов.

Вы также можете настроить диспетчер моделей, создав подклассы BaseSessionManager:

класс base_session.BaseSessionManager
encode( session_dict )

Возвращает указанный словарь сеанса, сериализованный и закодированный в виде строки.

Кодирование выполняется классом хранилища сеансов, привязанным к классу модели.

save( session_key , session_dict , expire_date )

Сохраняет данные сеанса для предоставленного сеансового ключа или удаляет сеанс, если данные пусты.

Настройка SessionStoreклассов достигается путем переопределения методов и свойств, описанных ниже:

класс backends.db.SessionStore

Реализует хранилище сеансов на основе базы данных.

classmethodget_model_class ()

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

create_model_instance( данные )

Возвращает новый экземпляр объекта модели сеанса, который представляет текущее состояние сеанса.

Переопределение этого метода дает возможность изменять данные модели сеанса перед их сохранением в базе данных.

класс 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».

Copyright ©2021 All rights reserved