Домой Edit me on GitHub

2020-12-05

Каналы передачи данных | Сетевое программирование | Базы данных | Основы Веб-программирования

Сессии

Фреймворк Pyramid имеет модуль pyramid.session, который содержит в себе несколько методов организации сессий.

Встроенный механизм сессий

Для того, чтобы использовать сессии, необходимо задать session factory во время конфигурации.

Очень простой, небезопасный способ создания сессии реализуется при помощи функции pyramid.session.UnencryptedCookieSessionFactoryConfig(). Он использует куки для хранения информации сеанса. Эта реализация имеет следующие ограничения:

  • значения куков не шифруется, поэтому их может просмотреть любой, кто имеет доступ к трафику или к браузеру.
  • Максимальное число байт для сессии 4000. Это подходит только для очень небольших наборов данных.

Функция pyramid.session.SignedCookieSessionFactory() шифрует данные, поэтому их тяжело подделать.

Добавление сессий в конфиг происходит следующим образом:

from pyramid.session import SignedCookieSessionFactory
my_session_factory = SignedCookieSessionFactory('itsaseekreet')

from pyramid.config import Configurator
config = Configurator()
config.set_session_factory(my_session_factory)

или через атрибут конструктора:

from pyramid.session import SignedCookieSessionFactory
my_session_factory = SignedCookieSessionFactory('itsaseekreet')

from pyramid.config import Configurator
config = Configurator(session_factory=my_session_factory)

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

После добавления сессий в конфиг, вы можете получить доступ к объектам сессии из любого запроса. Например:

from pyramid.response import Response

def myview(request):
    session = request.session

    if 'counter' in session:
        session['counter'] += 1
    else:
        session['counter'] = 1

    return Response(session['counter'])

Альтернативные механизмы сессий

  • pyramid_redis_sessions - предоставляет механизм сессий который использует хранилище Redis.
  • pyramid_beaker - использует в качестве бэкенда систему сессий Beaker.

В самом простом случае достаточно включить модуль в проект:

config = Configurator()
config.include('pyramid_beaker')

Теперь можно использовать сессии:

from pyramid.response import Response

def myview(request):
    session = request.session

    if 'counter' in session:
        session['counter'] += 1
    else:
        session['counter'] = 1

    return Response(session['counter'])

Всплывающие сообщения

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

Чтобы добавить сообщение, достаточно выполнить метод сессии flash().

request.session.flash('Congratulations "rm -rf /" successful')

Чтобы извлечь сообщение, нужно вызвать метод сессии pop_flash().

>>> request.session.flash('info message')
>>> request.session.pop_flash()
['info message']
>>> request.session.pop_flash()
[]

Для получения очереди, не извлекая сообщения из нее, нужно использовать метод peek_flash().

>>> request.session.flash('info message')
>>> request.session.peek_flash()
['info message']
>>> request.session.peek_flash()
['info message']
>>> request.session.pop_flash()
['info message']
>>> request.session.peek_flash()
[]

Например, всплывающие сообщения используются в модуле pyramid_sacrud. Это простой CRUD веб-интерфейс который выводит сообщения после какой-либо операции.

../../../_images/pyramid_sacrud_flash.png

Пример всплывающего сообщения после добавления записи в админке pyramid_sacrud

Cross-Site Request Forgery (CSRF)

Для получения токена используется метод session.get_csrf_token().

token = request.session.get_csrf_token()

Для создание нового токена:

token = request.session.new_csrf_token()

Пример добавления CSRF токена из текущей сессии в форму:

<form method="post" action="/myview">
  <input type="hidden" name="csrf_token" value="{{ request.session.get_csrf_token() }}">
  <input type="submit" value="Delete Everything">
</form>

Проверка токена:

from pyramid.session import check_csrf_token

def myview(request):
    # Require CSRF Token
    check_csrf_token(request)

    # ...

или

@view_config(request_method='POST', check_csrf=True, ...)
def myview(request):
    ...

Резюме

Previous: Шаблоны (Templates) Next: Админка