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

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

Разрешение сеансов

Сессии реализуются через кусок middleware.

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

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

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

Сеансы на основе кэша следует использовать только в том случае, если вы используете бэкенд кэша 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, вам также необходимо следовать инструкциям по настройке для using database-backed sessions.

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

Чтобы использовать сессии на основе файлов, установите параметр SESSION_ENGINE в значение "django.contrib.sessions.backends.file".

Возможно, вы также захотите установить параметр SESSION_FILE_PATH (который по умолчанию выводится из tempfile.gettempdir(), скорее всего /tmp), чтобы контролировать, где Django хранит файлы сессий. Обязательно проверьте, что ваш Web-сервер имеет разрешения на чтение и запись в это место.

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

Когда 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()

Удаляет данные текущей сессии и удаляет куки сессии. Это используется, если вы хотите, чтобы данные предыдущей сессии не могли быть снова доступны из браузера пользователя (например, функция django.contrib.auth.logout() вызывает ее).

Устанавливает тестовый файл cookie, чтобы определить, поддерживает ли браузер пользователя файлы cookie. В связи с тем, как работают куки, вы не сможете проверить это до следующего запроса страницы пользователем. Дополнительную информацию см. в разделе Setting test cookies ниже.

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

Удаляет тестовый файл 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, 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 для сериализации данных сессии. Если вы используете signed cookie session backend и SECRET_KEY известно злоумышленнику (в Django нет врожденной уязвимости, которая могла бы привести к утечке), то злоумышленник может вставить в сессию строку, которая, будучи распакованной, выполнит произвольный код на сервере. Техника для этого проста и легко доступна в интернете. Хотя для предотвращения несанкционированного вмешательства хранилище сессий 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, такие как байты, не относящиеся к стандарту UTF8, например '\xd9' (который поднимает UnicodeDecodeError), не могут быть сохранены.

Более подробно об ограничениях сериализации JSON смотрите в разделе Напишите свой собственный сериализатор.

class serializers.PickleSerializer

Поддерживает произвольные объекты Python, но, как описано выше, может привести к уязвимости удаленного выполнения кода, если SECRET_KEY станет известно злоумышленнику.

Напишите свой собственный сериализатор

Обратите внимание, что в отличие от PickleSerializer, JSONSerializer не может работать с произвольными типами данных Python. Как это часто бывает, существует компромисс между удобством и безопасностью. Если вы хотите хранить более сложные типы данных, включая datetime и Decimal в сессиях с поддержкой JSON, вам придется написать собственный сериализатор (или преобразовать такие значения в сериализуемый объект JSON перед хранением их в request.session). В то время как сериализация этих значений довольно проста (DjangoJSONEncoder может быть полезной), написание декодера, который может надежно получить обратно то же самое, что вы поместили, более хрупко. Например, вы рискуете вернуть 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 предоставляет простой способ проверить, принимает ли браузер пользователя cookies. Просто вызовите метод set_test_cookie() из request.session в представлении, и вызовите test_cookie_worked() в последующем представлении - не в том же вызове представления.

Это неудобное разделение между set_test_cookie() и test_cookie_worked() необходимо из-за того, как работают куки. Когда вы устанавливаете cookie, вы не можете сказать, принял ли его браузер, до следующего запроса браузера.

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

Обратите внимание, что сессионный cookie отправляется только тогда, когда сессия была создана или изменена. Если SESSION_SAVE_EVERY_REQUEST равно True, сессионный cookie будет отправляться при каждом запросе.

Аналогично, часть expires сеансового cookie обновляется при каждой отправке сеансового cookie.

Сессия не сохраняется, если код состояния ответа равен 500.

Сеансы длиной в браузер и постоянные сеансы

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

По умолчанию значение SESSION_EXPIRE_AT_BROWSER_CLOSE установлено на False, что означает, что сеансовые куки будут храниться в браузерах пользователей до тех пор, пока SESSION_COOKIE_AGE. Используйте это, если вы не хотите, чтобы людям приходилось входить в систему каждый раз, когда они открывают браузер.

Если SESSION_EXPIRE_AT_BROWSER_CLOSE установлено в значение True, Django будет использовать cookies длиной в браузер - cookies, срок действия которых истекает, как только пользователь закрывает браузер. Используйте это, если вы хотите, чтобы людям приходилось входить в систему каждый раз, когда они открывают браузер.

Эта настройка является глобальной по умолчанию и может быть перезаписана на уровне каждой сессии путем явного вызова метода set_expiry() из request.session, как описано выше в using sessions in views.

Примечание

Некоторые браузеры (например, Chrome) предоставляют настройки, позволяющие пользователям продолжать сеансы просмотра после закрытия и повторного открытия браузера. В некоторых случаях это может мешать настройке SESSION_EXPIRE_AT_BROWSER_CLOSE и предотвращать завершение сеансов при закрытии браузера. Пожалуйста, помните об этом при тестировании приложений Django, в которых включена настройка SESSION_EXPIRE_AT_BROWSER_CLOSE.

Очистка хранилища сеансов

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

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

Django не обеспечивает автоматическую очистку истекших сессий. Поэтому ваша работа заключается в регулярной очистке истекших сессий. Django предоставляет для этого команду управления очисткой: clearsessions. Рекомендуется вызывать эту команду на регулярной основе, например, в качестве ежедневного задания cron.

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

Безопасность сеанса

Поддомены внутри сайта могут устанавливать cookies на клиенте для всего домена. Это делает фиксацию сеанса возможной, если cookies разрешены с поддоменов, не контролируемых доверенными пользователями.

Например, злоумышленник может войти в good.example.com и получить действительную сессию для своей учетной записи. Если злоумышленник имеет контроль над bad.example.com, он может использовать его для отправки вам ключа сессии, поскольку поддомену разрешено устанавливать cookies на *.example.com. Когда вы посетите good.example.com, вы войдете в систему как злоумышленник и можете случайно ввести свои конфиденциальные личные данные (например, информацию о кредитной карте) в аккаунт злоумышленника.

Другой возможной атакой будет, если good.example.com установит свой SESSION_COOKIE_DOMAIN на "example.com", что приведет к отправке сессионных cookie с этого сайта на bad.example.com.

Технические детали

  • Словарь сессии принимает любое сериализуемое значение json при использовании JSONSerializer или любой picklable объект Python при использовании PickleSerializer. Дополнительную информацию см. в модуле pickle.
  • Данные сессии хранятся в таблице базы данных с именем django_session .
  • Django отправляет cookie только в том случае, если это необходимо. Если вы не задаете никаких данных сессии, он не будет отправлять сессионный cookie.

Объект SessionStore

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

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

class SessionStore(CachedDBStore):
    cache_key_prefix = 'mysessions.custom_cached_db_backend'

    # ...

Идентификаторы сессий в URL-адресах

Фреймворк сессий Django полностью и исключительно основан на cookie. Он не возвращается к помещению идентификаторов сессий в URL в качестве последнего средства, как это делает PHP. Это намеренное дизайнерское решение. Такое поведение не только делает URL уродливыми, но и делает ваш сайт уязвимым для кражи идентификатора сессии через заголовок «Referer».

Вернуться на верх