跳转到内容

会话管理

会话允许你跨多个 HTTP 请求存储用户特定的数据。由于 HTTP 是无状态的,会话使用 cookie 或其他机制来识别回访用户并检索其存储的数据。

使用 gin-contrib/sessions

gin-contrib/sessions 中间件提供了支持多种后端存储的会话管理:

Terminal window
go get github.com/gin-contrib/sessions

最简单的方式是将会话数据存储在加密的 cookie 中:

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,
})
选项描述
PathCookie 路径范围(默认:/
MaxAge生命周期(秒)。使用 -1 删除,0 为浏览器会话
HttpOnly防止 JavaScript 访问 cookie
Secure仅通过 HTTPS 发送 cookie
SameSite控制跨站 cookie 行为(LaxStrictNone

可用后端

后端用例
Cookiesessions/cookie简单应用,小型会话数据
Redissessions/redis生产环境,多实例部署
Memcachedsessions/memcached高性能缓存层
MongoDBsessions/mongoMongoDB 为主要数据存储时
PostgreSQLsessions/postgresPostgreSQL 为主要数据存储时

会话 vs JWT

方面会话JWT
存储服务端(Redis、数据库)客户端(令牌)
撤销简单(从存储中删除)困难(需要黑名单)
可扩展性需要共享存储无状态
数据大小服务端无限制受令牌大小限制

当你需要轻松撤销时使用会话(例如注销、封禁用户)。当你需要跨微服务的无状态认证时使用 JWT。

另请参阅