Сессии
HTTP не помнит прошлых запросов: каждый приходит как будто от нового посетителя. Сессия — хранилище данных конкретного посетителя между запросами. Браузер получает cookie с идентификатором сессии, а сервер по нему находит данные. На сессиях работают flash-сообщения, ошибки форм и вход пользователей.
Настройки
Пакет @adonisjs/session в наборе Web уже установлен. Способ хранения задаёт переменная в .env:
SESSION_DRIVER=cookie| Драйвер | Где хранятся данные |
|---|---|
cookie | В зашифрованной cookie у посетителя |
file | В файлах на сервере |
redis | В Redis |
memory | В памяти процесса, только для тестов |
Время жизни сессии и имя cookie указаны в config/session.ts.
Запись и чтение
Объект session есть в контексте запроса. Сделаем счётчик просмотренных статей:
// app/controllers/posts_controller.ts
async show({ params, session, view }: HttpContext) {
const post = await Post.findOrFail(params.id)
const viewed = session.get('viewedCount', 0)
session.put('viewedCount', viewed + 1)
return view.render('pages/posts/show', { post, viewed: viewed + 1 })
}get возвращает значение или значение по умолчанию, put сохраняет новое. Выведите {{ viewed }} в шаблоне и откройте несколько статей — число будет расти. В другом браузере счёт начнётся заново: у него своя сессия.
Методы сессии
| Метод | Что делает |
|---|---|
session.put('key', value) | Сохранить значение |
session.get('key', default) | Прочитать значение |
session.has('key') | Проверить, есть ли ключ |
session.forget('key') | Удалить ключ |
session.pull('key') | Прочитать и сразу удалить |
session.all() | Все данные сессии |
session.flash('key', value) | Сохранить до следующего запроса |
Список «недавно просмотренные»
В сессии можно хранить массивы и объекты:
// app/controllers/posts_controller.ts
const recent: number[] = session.get('recentPosts', [])
const updated = [post.id, ...recent.filter((id) => id !== post.id)].slice(0, 5)
session.put('recentPosts', updated)В сессии останутся номера пяти последних открытых статей, свежая — первой. По ним легко вывести блок «Вы недавно читали» запросом Post.query().whereIn('id', updated).
Сессия в шаблоне
Flash-сообщения выводят тегом @flashMessage, как в прошлом уроке. Остальные данные передавайте в шаблон из контроллера явно — так видно, откуда они берутся.
Частая ошибка
С драйвером cookie все данные сессии лежат в одной cookie, а браузер принимает cookie размером не больше 4 КБ. Если сложить в сессию целые модели или длинные списки, данные перестанут сохраняться. Храните в сессии только небольшие значения — идентификаторы, флажки, — а остальное берите из базы. Для больших данных переключите SESSION_DRIVER на file или redis.