Сессии — еще один способ хранить данные конкретных пользователей между запросами. Они работают по похожему на куки принципу. Для использования сессии нужно сперва настроить секретный ключ. Объект session
из пакета flask
используется для настройки и получения данных сессии. Объект session
работает как словарь, но он также может отслеживать изменения.
При использовании сессий данные хранятся в браузере как куки. Куки, используемые для хранения данных сессии — это куки сессии. Тем не менее в отличие от обычных куки Flask криптографически отмечает куки сессии. Это значит, что каждый может видеть содержимое куки, но не может их менять, не имея секретного ключа для подписи. Как только куки сессии настроены, каждый последующий запрос к серверу подтверждает подлинность куки с помощью такого же секретного ключа. Если Flask не удается это сделать, тогда его контент отклоняется, а браузер получает новые куки сессии.
Знакомые с сессиями из языка PHP заметят, что сессии во Flask немного отличаются. В PHP куки сессии не хранят данные о сессии, а только id сессии. Это уникальная строка, которую PHP создает для ассоциации данных сессии с куки. Данные сессии хранятся на сервере в виде файла. При получении запроса от пользователя PHP использует id сессии, чтобы найти данные сессии и отобразить их в коде. Такой тип сессий известен как серверный, а те, которые используются во Flask, называется клиентскими.
По умолчанию различий между куки и клиентскими сессиями во Flask не так много. В итоге клиентские сессии страдают от тех же недостатков, что и обычные куки:
- Не могут хранить конфиденциальную информацию, такую как пароли.
- Дают лишнюю нагрузку при каждом запросе.
- Не способны хранить больше 4 КБ.
- Ограничены в общем количестве куки для одного сайта
и так далее.
Единственное реальное различие между куки и клиентскими сессиями — Flask гарантирует, что содержимое куки сессии не может быть изменено пользователям (только если у него нет секретного ключа).
Для использования клиентских сессий во Flask можно или написать собственный интерфейс сессии или использовать расширения, такие как Flask-Session или Flask-KVSession.
Как читать, записывать и удалять данные сессии
Следующий код демонстрирует, как можно читать, записывать и удалять данные сессии. Откроем файл main2.py
, чтобы добавить следующий код после функции представления article()
:
from flask import Flask, render_template, request, redirect, url_for, flash, make_response, session
#...
@app.route('/visits-counter/')
def visits():
if 'visits' in session:
session['visits'] = session.get('visits') + 1 # чтение и обновление данных сессии
else:
session['visits'] = 1 # настройка данных сессии
return "Total visits: {}".format(session.get('visits'))
@app.route('/delete-visits/')
def delete_visits():
session.pop('visits', None) # удаление данных о посещениях
return 'Visits deleted'
#...
Стоит обратить внимание, что объект session
используется как обычный словарь. Если сервер не запущен, нужно его запустить и зайти на https://localhost:5000/visits-counter/
. На странице будет счетчик посещений:
Чтобы увеличить его, нужно несколько раз обновить страницу.
Flask отправляет куки сессии клиенту только при создании новой сессии или изменении существующей. При первом посещении https://localhost:5000/visits-counter/
будет исполнено тело else
в функции представления visits()
, в результате чего будет создана новая сессия. При создании новой сессии Flask отправит куки сессии клиенту. Последующие запросы к https://localhost:5000/visits-counter
приведут к исполнению кода в блоке if
, в котором обновляется значение счетчика visits
сессии. При изменении сессии будет создан новый файл куки, поэтому Flask отправит новые куки сессии клиенту.
Чтобы удалить данные сессии нужно зайти на https://localhost:5000/delete-visits/
.
Если сейчас открыть https://localhost:5000/visits-counter
, счетчик посещений снова будет показывать 1.
По умолчанию куки сессии существуют до тех пор, пока не закроется браузер. Чтобы продлить жизнь куки сессии, нужно установить значение True
для атрибута permanent
объекта session
. Когда значение permanent
равно True
, срок куки сессии будет равен permanent_session_lifetime
. permanent_session_lifetime
— это атрибут datetime.timedelta
объекта Flask
. Его значение по умолчанию равно 31 дню. Изменить его можно, выбрав новое значение для атрибута permanent_session_lifetime
, используя ключ настройки PERMANENT_SESSION_LIFETIME
.
import datetime
app = Flask(__name__)
app.permanent_session_lifetime = datetime.timedelta(days=365)
# app.config['PERMANENT_SESSION_LIFETIME'] = datetime.timedelta(days=365)
Как и request
, объект sessions
доступен в шаблонах.
Изменение данных сессии
Примечание: перед тем как следовать инструкции, нужно удалить куки, установленные локальным хостом.
Большую часть времени объект session
автоматически подхватывает изменения. Но бывают случаи, например изменение структуры изменяемых данных, которые не подхватываются автоматически. Для таких ситуаций нужно установить значение True
для атрибута modified
объекта session
. Если этого не сделать, Flask не будет отправлять обновленные куки клиенту. Следующий код показывает, как использовать атрибут modified
объекта session
. Откроем файл main2.py
, чтобы добавить следующий код перед функцией представления delete_visitis()
.
#...
@app.route('/session/')
def updating_session():
res = str(session.items())
cart_item = {'pineapples': '10', 'apples': '20', 'mangoes': '30'}
if 'cart_item' in session:
session['cart_item']['pineapples'] = '100'
session.modified = True
else:
session['cart_item'] = cart_item
return res
#...
При первом посещении https://localhost:5000/session/
код в блоке else
будет исполнен. Он создаст новую сессию, где данные сессии будут в виде словаря. Последующий запрос к https://localhost:5000/session/
обновляет данные сессии, установив количество «ананасов» на значении 100. В следующей строке атрибут modified
получает значение True
, потому что без него Flask не будет отправлять обновленные куки сессии клиенту.
Если сервер не запущен, его следует запустить и зайти на https://localhost:5000/session/
. Отобразится пустой словарь session
, потому что у браузера еще нет куки сессии, которые он мог бы отправить серверу:
Если страницу перезагрузить, в словаре session
будет уже «10 ананасов»:
Перезагрузив страницу в третий раз, можно увидеть, что словарь session
имеет значение «ананасов» равное 100, а не 10:
Объект сессии подхватил изменение благодаря атрибуту modified
. Удостовериться в этом можно, удалив куки сессии и закомментировав строку, где для атрибута modified
устанавливается значение True
. Теперь после первого запроса значение словаря сессии будет равно «10 ананасам».
Это все, что нужно знать о сессиях во Flask. И важно не забывать, что по умолчанию сессии во Flask являются клиентскими.