SCS: Управление HTTP-сессиями для Go
Менеджер сессий для GO
Возможности
Автоматическая загрузка и сохранение данных сессии через middleware
Выбор из 19 серверных хранилищ для сессий, включая:
- Базы данных: PostgreSQL, MySQL, MSSQL, SQLite
- Кэш-системы: Redis
- Поддержка пользовательских хранилищ
Расширенные функции:
- Несколько сессий на один запрос
- “Flash”-сообщения (одноразовые уведомления)
- Регенерация токенов сессии
- Таймауты: по бездействию и абсолютные
- Функция “запомнить меня”
Гибкость:
- Простота расширения и кастомизации
- Передача токенов сессии через HTTP-заголовки или тела запросов/ответов
Производительность:
- Оптимизированная архитектура
- Меньший размер, выше скорость и меньше потребление памяти по сравнению с gorilla/sessions
Установка
Этот пакет требует Go версии 1.12 или новее.
go get github.com/alexedwards/scs/v2
Примечание: Если вы используете традиционный механизм GOPATH для управления зависимостями (вместо модулей), вам нужно использовать go get и импортировать github.com/alexedwards/scs без суффикса v2.
Рекомендуется использовать версионные релизы. Код в ветке tip может содержать экспериментальные функции, которые могут измениться.
Базовое использование
SCS реализует механизм управления сессиями в соответствии с рекомендациями по безопасности OWASP. Данные сессии хранятся на сервере, а случайно сгенерированный уникальный токен сессии (или ID сессии) передается клиенту и обратно через cookie сессии.
package main
import (
"io"
"net/http"
"time"
"github.com/alexedwards/scs/v2"
)
var sessionManager *scs.SessionManager
func main() {
// Инициализация нового менеджера сессий и настройка времени жизни сессии
sessionManager = scs.New()
sessionManager.Lifetime = 24 * time.Hour
mux := http.NewServeMux()
mux.HandleFunc("/put", putHandler)
mux.HandleFunc("/get", getHandler)
// Оберните ваши обработчики middleware LoadAndSave()
http.ListenAndServe(":4000", sessionManager.LoadAndSave(mux))
}
func putHandler(w http.ResponseWriter, r *http.Request) {
// Сохранение нового ключа и значения в данных сессии
sessionManager.Put(r.Context(), "message", "Hello from a session!")
}
func getHandler(w http.ResponseWriter, r *http.Request) {
// Использование вспомогательной функции GetString для получения строкового значения
// по ключу. Возвращается нулевое значение, если ключ не существует.
msg := sessionManager.GetString(r.Context(), "message")
io.WriteString(w, msg)
}
Пример работы с curl:
$ curl -i --cookie-jar cj --cookie cj localhost:4000/put
HTTP/1.1 200 OK
Cache-Control: no-cache="Set-Cookie"
Set-Cookie: session=lHqcPNiQp_5diPxumzOklsSdE-MJ7zyU6kjch1Ee0UM; Path=/; Expires=Sat, 27 Apr 2019 10:28:20 GMT; Max-Age=86400; HttpOnly; SameSite=Lax
Vary: Cookie
Date: Fri, 26 Apr 2019 10:28:19 GMT
Content-Length: 0
$ curl -i --cookie-jar cj --cookie cj localhost:4000/get
HTTP/1.1 200 OK
Date: Fri, 26 Apr 2019 10:28:24 GMT
Content-Length: 21
Content-Type: text/plain; charset=utf-8
Hello from a session!
Настройка поведения сессии
Поведение сессии можно настроить через поля SessionManager:
sessionManager = scs.New()
sessionManager.Lifetime = 3 * time.Hour // Общее время жизни сессии
sessionManager.IdleTimeout = 20 * time.Minute // Таймаут бездействия
sessionManager.Cookie.Name = "session_id" // Имя cookie
sessionManager.Cookie.Domain = "example.com" // Домен cookie
sessionManager.Cookie.HttpOnly = true // Доступ только через HTTP
sessionManager.Cookie.Path = "/example/" // Путь cookie
sessionManager.Cookie.Persist = true // Сохранение после закрытия браузера
sessionManager.Cookie.SameSite = http.SameSiteStrictMode // Политика SameSite
sessionManager.Cookie.Secure = true // Только HTTPS
sessionManager.Cookie.Partitioned = true // Partitioned cookies
Документация по всем доступным настройкам и их значениям по умолчанию доступна [здесь](ссылка на документацию).
Работа с данными сессии
Установка и получение данных
Данные можно устанавливать с помощью метода Put() и получать с помощью Get(). Для распространённых типов данных предусмотрены вспомогательные методы, такие как GetString(), GetInt() и GetBytes(). Полный список вспомогательных методов доступен в документации.
Одноразовое получение данных
Метод Pop() (и соответствующие вспомогательные методы для распространённых типов данных) работает как одноразовый Get() - извлекает данные и сразу удаляет их из сессии. Это полезно для реализации функционала “flash”-сообщений, которые показываются пользователю только один раз.
Дополнительные функции
Exists() - возвращает bool, указывающий на наличие ключа в данных сессииKeys() - возвращает отсортированный срез всех ключей в данных сессии
Удаление данных
Отдельные элементы можно удалить с помощью метода Remove(). Для полной очистки данных сессии используйте метод Destroy(). После вызова Destroy() любые последующие операции в рамках того же цикла запроса приведут к созданию новой сессии - с новым токеном и временем жизни.
Хранение пользовательских типов
SCS использует кодировку gob для хранения данных сессии. Пользовательские типы должны быть зарегистрированы в пакете encoding/gob. Поля структур пользовательских типов должны быть экспортируемыми (начинаться с заглавной буквы), чтобы быть видимыми для пакета encoding/gob. Пример работы можно посмотреть [здесь](ссылка на пример).
Загрузка и сохранение сессий
Стандартное использование
Большинство приложений используют middleware LoadAndSave(). Этот middleware:
- Загружает и сохраняет данные сессии в хранилище
- Управляет передачей токена сессии клиенту через cookie
Кастомизация поведения
Если требуется изменить стандартное поведение (например, передавать токен сессии через HTTP-заголовки или устанавливать распределённую блокировку токена сессии на время запроса), можно создать собственный middleware, используя код LoadAndSave() в качестве шаблона. Пример доступен [здесь](ссылка на пример).
Точный контроль
Для более точного управления можно загружать и сохранять сессии непосредственно в обработчиках запросов или в любом другом месте приложения. Пример такого подхода приведён [здесь](ссылка на пример).
Настройка хранилища сессий
Хранилище по умолчанию
По умолчанию SCS использует in-memory хранилище для данных сессии. Это:
- Удобно (не требует настройки)
- Очень быстро
- Но все данные теряются при остановке или перезапуске приложения
Это решение подходит для:
- Приложений, где допустима потеря данных в обмен на высокую производительность
- Прототипирования
- Тестирования
Продукционные решения
Для большинства рабочих приложений рекомендуется использовать постоянные хранилища, такие как:
- PostgreSQL
- MySQL
- Другие поддерживаемые системы (список ниже)
Полный список поддерживаемых хранилищ сессий с инструкциями по использованию доступен в таблице (ссылки в оригинальной документации).
Поддерживаемые хранилища сессий
Вот полный список доступных хранилищ сессий в SCS с их характеристиками:
| Пакет | Бэкенд | Встроенный | In-Memory | Мультипроцессорный |
|---|
badgerstore | BadgerDB | Да | Нет | Нет |
boltstore | BBolt | Да | Нет | Нет |
bunstore | Bun ORM (PostgreSQL/MySQL/MSSQL/SQLite) | Нет | Нет | Да |
buntdbstore | BuntDB | Да | Да | Нет |
cockroachdbstore | CockroachDB | Нет | Нет | Да |
consulstore | Consul | Нет | Да | Да |
etcdstore | Etcd | Нет | Нет | Да |
firestore | Google Cloud Firestore | Нет | ? | Да |
gormstore | GORM ORM (PostgreSQL/MySQL/SQLite/MSSQL/TiDB) | Нет | Нет | Да |
leveldbstore | LevelDB | Да | Нет | Нет |
memstore | In-memory (по умолчанию) | Да | Да | Нет |
mongodbstore | MongoDB | Нет | Нет | Да |
mssqlstore | Microsoft SQL Server | Нет | Нет | Да |
mysqlstore | MySQL | Нет | Нет | Да |
pgxstore | PostgreSQL (драйвер pgx) | Нет | Нет | Да |
postgresstore | PostgreSQL (драйвер pq) | Нет | Нет | Да |
redisstore | Redis | Нет | Да | Да |
sqlite3store | SQLite3 (CGO-драйвер mattn/go-sqlite3) | Да | Нет | Да |
Ключевые характеристики:
- Встроенный - Не требует отдельного сервера/процесса
- In-Memory - Хранит данные в оперативной памяти
- Мультипроцессорный - Поддерживает работу в распределённой среде
Пользовательские хранилища
SCS также поддерживает создание собственных хранилищ сессий. Подробная информация доступна [здесь](ссылка на документацию).
Выбор хранилища зависит от требований вашего приложения:
- Для тестирования/разработки -
memstore или buntdbstore - Для продакшена -
postgresstore, mysqlstore или redisstore - Для встраиваемых решений -
badgerstore или boltstore
Использование пользовательских хранилищ сессий
Базовый интерфейс хранилища
Интерфейс scs.Store определяет контракт для пользовательских хранилищ сессий. Любой объект, реализующий этот интерфейс, может быть установлен как хранилище при настройке сессии.
type Store interface {
// Delete удаляет токен сессии и соответствующие данные из хранилища.
// Если токен не существует, Delete должен завершиться без ошибки.
Delete(token string) (err error)
// Find возвращает данные для указанного токена сессии.
// Если токен не найден или истек, возвращает found=false.
// Для повреждённых токенов также возвращает found=false.
// Ошибка возвращается только для системных сбоев.
Find(token string) (b []byte, found bool, err error)
// Commit добавляет или обновляет данные сессии с указанным сроком действия.
Commit(token string, b []byte, expiry time.Time) (err error)
}
type IterableStore interface {
// All возвращает map со всеми активными (не истекшими) сессиями.
// Ключ - токен сессии, значение - данные сессии.
// Если активных сессий нет, возвращает пустую (не nil) map.
All() (map[string][]byte, error)
}
Интерфейс с поддержкой контекста
scs.CtxStore расширяет базовый интерфейс, добавляя методы с поддержкой context.Context:
type CtxStore interface {
Store
// Версии методов с контекстом
DeleteCtx(ctx context.Context, token string) (err error)
FindCtx(ctx context.Context, token string) (b []byte, found bool, err error)
CommitCtx(ctx context.Context, token string, b []byte, expiry time.Time) (err error)
}
type IterableCtxStore interface {
// AllCtx - версия All с поддержкой контекста
AllCtx(ctx context.Context) (map[string][]byte, error)
}
Защита от фиксации сессии
Для предотвращения атак фиксации сессии следует обновлять токен сессии при любом изменении уровня привилегий. Обычно это делается при входе/выходе пользователя:
func loginHandler(w http.ResponseWriter, r *http.Request) {
userID := 123
// 1. Сначала обновляем токен сессии
err := sessionManager.RenewToken(r.Context())
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// 2. Затем изменяем уровень привилегий
sessionManager.Put(r.Context(), "userID", userID)
}
Важные моменты:
RenewToken() должен вызываться ДО изменения данных сессии- При ошибке обновления токена следует прервать операцию
- Такой же подход применяется при выходе пользователя
Этот механизм гарантирует, что после аутентификации сессия получает новый токен, делая недействительным любой ранее перехваченный злоумышленником токен.
Расширенные возможности SCS
Несколько сессий в одном запросе
SCS позволяет использовать несколько параллельных сессий в рамках одного запроса с разными:
- Временем жизни
- Хранилищами данных
Пример реализации доступен [здесь](ссылка на пример).
Перебор всех сессий
Для работы со всеми активными сессиями SCS предоставляет метод Iterate(), который принимает функцию-обработчик:
err := sessionManager.Iterate(r.Context(), func(ctx context.Context) error {
userID := sessionManager.GetInt(ctx, "userID")
if userID == 4 {
// Удаляем сессию для пользователя с ID=4
return sessionManager.Destroy(ctx)
}
return nil
})
if err != nil {
log.Fatal(err)
}
Ключевые особенности:
- Обработчик получает контекст каждой сессии
- Можно выполнять любые операции с сессией
- Возврат ошибки прерывает процесс итерации
Потоковая передача ответов (Flushing)
Поддержка потоковой передачи реализована через http.NewResponseController (доступно в Go ≥1.20):
func flushingHandler(w http.ResponseWriter, r *http.Request) {
sessionManager.Put(r.Context(), "message", "Hello from flushing handler!")
rc := http.NewResponseController(w)
for i := 0; i < 5; i++ {
fmt.Fprintf(w, "Write %d\n", i)
err := rc.Flush()
if err != nil {
log.Println(err)
return
}
time.Sleep(time.Second)
}
}
Важно:
- Стандартная реализация middleware
LoadAndSave() не поддерживает интерфейс http.Flusher - Потоковая передача работает только в Go версии 1.20 и выше
Полный рабочий пример можно найти [здесь](ссылка на пример).
Совместимость с фреймворками
Возможны проблемы при интеграции с фреймворками, которые не передают контекст запроса через стандартные middleware:
- Для Echo рекомендуется использовать пакет echo-scs-session
- Fiber и другие нестандартные фреймворки могут требовать дополнительной адаптации
Вклад в разработку
Приветствуются:
- Исправления ошибок
- Улучшения документации
Для новых функций или изменений поведения:
- Создайте issue для обсуждения
- После согласования - отправляйте PR
Для новых реализаций хранилищ:
- Как правило, не добавляются в основной репозиторий
- Можно создать отдельный репозиторий и добавить ссылку в README через PR
1 - Официальное API SCS: Управление HTTP-сессиями для Go
Менеджер сессий для GO
Использование пользовательских хранилищ сеансов scs.Store определяет интерфейс для пользовательских хранилищ сеансов. Любой объект, реализующий этот интерфейс, может быть установлен как хранилище при настройке сеанса.
Работа с пользовательскими хранилищами сессий
Интерфейсы хранилищ
Базовый интерфейс Store
Определяет контракт для реализации пользовательских хранилищ:
type Store interface {
// Delete удаляет токен и данные сессии из хранилища
// Если токен не существует - операция должна завершиться успешно
Delete(token string) error
// Find ищет данные по токену сессии
// Возвращает:
// - данные (если найдены)
// - флаг found (найдено/не найдено)
// - ошибку (только для системных сбоев)
Find(token string) ([]byte, bool, error)
// Commit сохраняет или обновляет данные сессии
Commit(token string, data []byte, expiry time.Time) error
}
Интерфейс IterableStore
Добавляет возможность перебора всех сессий:
type IterableStore interface {
// All возвращает все активные (не истекшие) сессии
// В формате map[токен]данные
All() (map[string][]byte, error)
}
Версии с поддержкой контекста
CtxStore
Расширяет базовый интерфейс с добавлением context.Context:
type CtxStore interface {
Store
// Версии методов с поддержкой контекста
DeleteCtx(ctx context.Context, token string) error
FindCtx(ctx context.Context, token string) ([]byte, bool, error)
CommitCtx(ctx context.Context, token string, data []byte, expiry time.Time) error
}
IterableCtxStore
Аналогично для перебора сессий:
type IterableCtxStore interface {
AllCtx(ctx context.Context) (map[string][]byte, error)
}
Защита от фиксации сессии
Для предотвращения атак фиксации сессии необходимо:
func loginHandler(w http.ResponseWriter, r *http.Request) {
userID := 123
// 1. Сначала обновляем токен сессии
if err := sessionManager.RenewToken(r.Context()); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 2. Затем сохраняем данные пользователя
sessionManager.Put(r.Context(), "userID", userID)
}
Ключевые моменты:
- Всегда обновляйте токен при изменении прав доступа
- Порядок операций критически важен
- Такой же подход применяйте при выходе пользователя
Это гарантирует, что после аутентификации будет создан новый токен сессии, делая недействительными любые ранее перехваченные токены.
Типы данных в SCS
Интерфейс Codec
Добавлен в v2.2.0
type Codec interface {
// Encode преобразует срок действия и значения сессии в байтовый срез
Encode(deadline time.Time, values map[string]interface{}) ([]byte, error)
// Decode восстанавливает срок действия и значения сессии из байтового среза
Decode([]byte) (deadline time.Time, values map[string]interface{}, err error)
}
Интерфейс для кодирования/декодирования данных сессии при работе с хранилищем.
Интерфейс CtxStore
Добавлен в v2.5.0
type CtxStore interface {
Store
// Версии методов с поддержкой контекста:
DeleteCtx(ctx context.Context, token string) error
FindCtx(ctx context.Context, token string) ([]byte, bool, error)
CommitCtx(ctx context.Context, token string, b []byte, expiry time.Time) error
}
Расширенный интерфейс хранилища с поддержкой context.Context.
Структура GobCodec
Добавлена в v2.3.1
Реализация Codec с использованием encoding/gob для сериализации данных.
Методы GobCodec:
// Decode преобразует байты в срок действия и данные сессии
func (GobCodec) Decode(b []byte) (time.Time, map[string]interface{}, error)
// Encode сериализует данные сессии в байтовый срез
func (GobCodec) Encode(deadline time.Time, values map[string]interface{}) ([]byte, error)
Интерфейс IterableCtxStore
Добавлен в v2.5.0
type IterableCtxStore interface {
// AllCtx возвращает все активные сессии (с поддержкой контекста)
AllCtx(ctx context.Context) (map[string][]byte, error)
}
Интерфейс для перечислимых хранилищ с поддержкой context.Context.
Интерфейс IterableStore
Добавлен в v2.5.0
type IterableStore interface {
// All возвращает все активные (не истекшие) сессии
All() (map[string][]byte, error)
}
Базовый интерфейс для хранилищ с возможностью перебора сессий.
Ключевые особенности:
Codec - абстракция для сериализации данныхGobCodec - стандартная реализация через encoding/gobCtxStore добавляет поддержку контекста к базовому хранилищу- Интерфейсы
Iterable позволяют работать со всеми сессиями
Конфигурация сессий в SCS
Структура SessionCookie
type SessionCookie struct {
// Имя cookie сессии (не должно содержать спецсимволы)
// По умолчанию: "session"
Name string
// Домен cookie (по умолчанию - текущий домен)
Domain string
// HttpOnly флаг (по умолчанию true)
HttpOnly bool
// Путь cookie (по умолчанию "/")
Path string
// Сохранять cookie после закрытия браузера (по умолчанию true)
Persist bool
// Политика SameSite (по умолчанию Lax)
SameSite http.SameSite
// Secure флаг (только HTTPS, по умолчанию false)
Secure bool
}
Настройки cookie для управления сессиями.
Структура SessionManager
Добавлена в v2.1.0
type SessionManager struct {
// Таймаут бездействия (опционально)
IdleTimeout time.Duration
// Максимальное время жизни сессии (по умолчанию 24 часа)
Lifetime time.Duration
// Хранилище сессий
Store Store
// Настройки cookie
Cookie SessionCookie
// Кодек для сериализации данных (по умолчанию GobCodec)
Codec Codec
// Обработчик ошибок (по умолчанию HTTP 500)
ErrorFunc func(http.ResponseWriter, *http.Request, error)
// Хэшировать токен в хранилище
HashTokenInStore bool
// содержит скрытые поля
}
Основные настройки:
- IdleTimeout: автоматическое завершение неактивных сессий
- Lifetime: абсолютное время жизни сессии
- Store: подключение к Redis, PostgreSQL и другим хранилищам
- Cookie: тонкая настройка параметров безопасности cookie
- Codec: кастомная сериализация данных
- ErrorFunc: обработка ошибок на уровне middleware
Рекомендации по безопасности:
- Всегда устанавливайте
Secure=true в production - Используйте
SameSite=Strict для критичных операций - Для API можно отключить
HttpOnly и работать через заголовки - Регулируйте
Lifetime в соответствии с требованиями приложения
Пример инициализации:
manager := scs.New()
manager.Lifetime = 12 * time.Hour
manager.Cookie.Secure = true
manager.Cookie.SameSite = http.SameSiteStrictMode
manager.Store = redisstore.New(redisPool)
Методы SessionManager
Основные функции
New
Добавлено в v2.1.0
func New() *SessionManager
Создает новый менеджер сессий с настройками по умолчанию. Потокобезопасен.
Clear (устаревший)
func (s *SessionManager) Clear(ctx context.Context) error
Очищает все данные текущей сессии, не затрагивая токен и время жизни. Если данных нет - операция не выполняется.
Управление сессиями
Commit
Добавлено в v2.1.0
func (s *SessionManager) Commit(ctx context.Context) (string, time.Time, error)
Сохраняет данные сессии в хранилище и возвращает:
- Токен сессии
- Время истечения
- Ошибку (если есть)
Обычно используется автоматически middleware LoadAndSave().
Deadline
Добавлено в v2.5.0
func (s *SessionManager) Deadline(ctx context.Context) time.Time
Возвращает абсолютное время истечения сессии. При использовании IdleTimeout сессия может завершиться раньше из-за неактивности.
Destroy
Добавлено в v2.1.0
func (s *SessionManager) Destroy(ctx context.Context) error
Полностью удаляет сессию:
- Удаляет данные из хранилища
- Помечает сессию как уничтоженную
- Новые операции создадут свежую сессию
Работа с данными
Exists
Добавлено в v2.1.0
func (s *SessionManager) Exists(ctx context.Context, key string) bool
Проверяет наличие ключа в данных сессии.
Get
Добавлено в v2.1.0
func (s *SessionManager) Get(ctx context.Context, key string) interface{}
Возвращает значение по ключу как interface{}, требующее приведения типа:
foo, ok := session.Get(ctx, "foo").(string)
if !ok {
return errors.New("ошибка приведения типа")
}
GetBool
Добавлено в v2.1.0
func (s *SessionManager) GetBool(ctx context.Context, key string) bool
Возвращает значение как bool (по умолчанию false если ключ отсутствует или тип не совпадает).
GetBytes
Добавлено в v2.1.0
func (s *SessionManager) GetBytes(ctx context.Context, key string) []byte
Возвращает значение как []byte (по умолчанию nil).
Методы работы с данными сессии
Получение типизированных значений
GetFloat
func (s *SessionManager) GetFloat(ctx context.Context, key string) float64
Возвращает значение как float64 (0 если ключ отсутствует или тип не совпадает)
GetInt
func (s *SessionManager) GetInt(ctx context.Context, key string) int
Возвращает значение как int (0 если ключ отсутствует)
GetInt32
func (s *SessionManager) GetInt32(ctx context.Context, key string) int32
Возвращает значение как int32 (0 по умолчанию)
GetInt64
func (s *SessionManager) GetInt64(ctx context.Context, key string) int64
Возвращает значение как int64 (0 по умолчанию)
GetString
func (s *SessionManager) GetString(ctx context.Context, key string) string
Возвращает строковое значение (пустая строка "" если ключ отсутствует)
GetTime
func (s *SessionManager) GetTime(ctx context.Context, key string) time.Time
Возвращает значение времени (time.IsZero() == true если ключ отсутствует)
Управление сессиями
Iterate
func (s *SessionManager) Iterate(ctx context.Context, fn func(context.Context) error) error
Итерируется по всем активным сессиям и выполняет функцию fn для каждой. Требует поддержки итерации в хранилище.
Keys
func (s *SessionManager) Keys(ctx context.Context) []string
Возвращает отсортированный список всех ключей сессии (пустой слайс если данных нет)
Middleware и загрузка данных
Load
func (s *SessionManager) Load(ctx context.Context, token string) (context.Context, error)
Загружает данные сессии по токену и возвращает новый контекст. Создает новую сессию если токен не найден.
LoadAndSave
func (s *SessionManager) LoadAndSave(next http.Handler) http.Handler
Middleware для автоматической загрузки/сохранения сессии и управления cookie.
Пример:
router := http.NewServeMux()
router.HandleFunc("/", handler)
// Обертывание роутера middleware
app := sessionManager.LoadAndSave(router)
http.ListenAndServe(":4000", app)
Методы управления сессиями в SCS
Работа с данными сессии
MergeSession (v2.5.0+)
func (s *SessionManager) MergeSession(ctx context.Context, token string) error
Объединяет данные из другой сессии (полезно при OAuth-редиректах). Для полной замены данных используйте Clear().
Pop-методы
Одноразовое получение данных с удалением ключа:
func (s *SessionManager) Pop(ctx context.Context, key string) interface{}
func (s *SessionManager) PopBool(ctx context.Context, key string) bool
func (s *SessionManager) PopBytes(ctx context.Context, key string) []byte
func (s *SessionManager) PopFloat(ctx context.Context, key string) float64
func (s *SessionManager) PopInt(ctx context.Context, key string) int
func (s *SessionManager) PopString(ctx context.Context, key string) string
func (s *SessionManager) PopTime(ctx context.Context, key string) time.Time
Пример для flash-сообщений:
// Установка
sessionManager.Put(ctx, "flash", "Сообщение")
// Получение с удалением
msg := sessionManager.PopString(ctx, "flash")
Основные операции
Put (v2.1.0+)
func (s *SessionManager) Put(ctx context.Context, key string, val interface{})
Добавляет или обновляет значение в сессии. Автоматически помечает сессию как измененную.
Remove (v2.1.0+)
func (s *SessionManager) Remove(ctx context.Context, key string)
Удаляет ключ из сессии. Если ключ не существует - операция игнорируется.
Управление токенами и временем жизни
RenewToken (v2.1.0+)
func (s *SessionManager) RenewToken(ctx context.Context) error
Генерирует новый токен сессии, сохраняя данные. Критично для:
- Входа/выхода пользователей
- Изменения прав доступа
- Защиты от фиксации сессии
RememberMe (v2.5.0+)
func (s *SessionManager) RememberMe(ctx context.Context, val bool)
Управляет постоянством сессии (работает только при Cookie.Persist = false).
SetDeadline (v2.7.0+)
func (s *SessionManager) SetDeadline(ctx context.Context, expire time.Time)
Устанавливает абсолютное время истечения сессии (может быть перекрыто IdleTimeout).
Информационные методы
Status (v2.1.0+)
func (s *SessionManager) Status(ctx context.Context) Status
Возвращает текущее состояние сессии (новые/измененные/уничтоженные).
Token (v2.5.0+)
func (s *SessionManager) Token(ctx context.Context) string
Возвращает токен сессии (пустую строку до коммита).
WriteSessionCookie (v2.3.0+)
func (s *SessionManager) WriteSessionCookie(ctx context.Context, w http.ResponseWriter, token string, expiry time.Time)
Низкоуровневый метод записи cookie (обычно используется через middleware).
Типы данных и интерфейсы SCS
Тип Status
Статус представляет состояние данных сессии в течение цикла запроса.
Константы статусов:
const (
// Unmodified - данные сессии не изменялись
Unmodified Status = iota
// Modified - данные были изменены
Modified
// Destroyed - сессия была уничтожена
Destroyed
)
Использование:
status := sessionManager.Status(ctx)
switch status {
case scs.Unmodified:
// Сессия не изменялась
case scs.Modified:
// Требуется сохранение изменений
case scs.Destroyed:
// Сессия закрыта
}
Интерфейс Store
type Store interface {
// Delete удаляет токен и данные сессии
// Если токен не существует - операция игнорируется
Delete(token string) error
// Find ищет данные по токену сессии
// Возвращает:
// - данные (если найдены)
// - флаг существования
// - ошибку (только для системных сбоев)
Find(token string) ([]byte, bool, error)
// Commit сохраняет/обновляет данные сессии
Commit(token string, data []byte, expiry time.Time) error
}
Базовый интерфейс для реализации хранилищ сессий.
Особенности реализации:
- Delete должен быть идемпотентным
- Find возвращает
found=false для:- Несуществующих токенов
- Истекших сессий
- Поврежденных данных
- Commit должен перезаписывать существующие данные
Пример проверки сессии:
data, found, err := store.Find(token)
if err != nil {
// Обработка системной ошибки
}
if !found {
// Сессия не существует/истекла
}
Этот интерфейс позволяет интегрировать SCS с любыми системами хранения данных.