Перейти к содержимому

Управление сессиями

Сессии позволяют хранить данные, специфичные для пользователя, между несколькими HTTP-запросами. Поскольку HTTP является протоколом без сохранения состояния, сессии используют cookies или другие механизмы для идентификации возвращающихся пользователей и получения их сохранённых данных.

Использование gin-contrib/sessions

Middleware gin-contrib/sessions предоставляет управление сессиями с несколькими хранилищами:

Окно терминала
go get github.com/gin-contrib/sessions

Сессии на основе cookies

Простейший подход — хранение данных сессии в зашифрованных cookies:

package main
import (
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// Create cookie-based session store with a secret key
store := cookie.NewStore([]byte("your-secret-key"))
r.Use(sessions.Sessions("mysession", store))
r.GET("/login", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("user", "john")
session.Save()
c.JSON(http.StatusOK, gin.H{"message": "logged in"})
})
r.GET("/profile", func(c *gin.Context) {
session := sessions.Default(c)
user := session.Get("user")
if user == nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "not logged in"})
return
}
c.JSON(http.StatusOK, gin.H{"user": user})
})
r.GET("/logout", func(c *gin.Context) {
session := sessions.Default(c)
session.Clear()
session.Save()
c.JSON(http.StatusOK, gin.H{"message": "logged out"})
})
r.Run(":8080")
}

Сессии на основе Redis

Для продакшн-приложений храните сессии в Redis для масштабирования между несколькими экземплярами:

package main
import (
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/redis"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// Connect to Redis for session storage
store, err := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
if err != nil {
panic(err)
}
r.Use(sessions.Sessions("mysession", store))
r.GET("/set", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("count", 1)
session.Save()
c.JSON(http.StatusOK, gin.H{"count": 1})
})
r.GET("/get", func(c *gin.Context) {
session := sessions.Default(c)
count := session.Get("count")
c.JSON(http.StatusOK, gin.H{"count": count})
})
r.Run(":8080")
}

Параметры сессии

Настройте поведение сессии с помощью sessions.Options:

session := sessions.Default(c)
session.Options(sessions.Options{
Path: "/",
MaxAge: 3600, // Session expires in 1 hour (seconds)
HttpOnly: true, // Prevent JavaScript access
Secure: true, // Only send over HTTPS
SameSite: http.SameSiteLaxMode,
})
ПараметрОписание
PathОбласть действия пути cookie (по умолчанию: /)
MaxAgeВремя жизни в секундах. -1 для удаления, 0 для сессии браузера
HttpOnlyПредотвращает доступ JavaScript к cookie
SecureОтправлять cookie только через HTTPS
SameSiteКонтролирует поведение кросс-сайтовых cookies (Lax, Strict, None)

Доступные хранилища

ХранилищеПакетСценарий использования
Cookiesessions/cookieПростые приложения, малый объём данных сессии
Redissessions/redisПродакшн, многоэкземплярные развёртывания
Memcachedsessions/memcachedВысокопроизводительный слой кеширования
MongoDBsessions/mongoКогда MongoDB — ваше основное хранилище
PostgreSQLsessions/postgresКогда PostgreSQL — ваше основное хранилище

Сессии vs JWT

АспектСессииJWT
ХранениеНа стороне сервера (Redis, БД)На стороне клиента (токен)
ОтзывПросто (удалить из хранилища)Сложно (требует блокировочного списка)
МасштабируемостьНужно общее хранилищеБез состояния
Размер данныхНеограничен на сервереОграничен размером токена

Используйте сессии, когда нужен простой отзыв (например, выход, блокировка пользователя). Используйте JWT, когда нужна аутентификация без состояния между микросервисами.

Смотрите также