Go 语言 Gin 框架会话控制(Session/Cookie)最全实战教程
·
🏷️ 标签:Go Gin 会话控制 Cookie Session 登录认证 中间件 Web开发 📝 适用人群:Go 初学者、Gin 框架开发者、课程实训、作业报告、面试必背 💡 文章亮点:全网最细、逐行注释、通俗易懂、无任何省略、可直接运行,从 HTTP 无状态讲到 Cookie 原理、Session 原理、完整登录实战、拦截器、生命周期、安全配置,新手也能完全学会!
一、前言:为什么需要会话控制?
1.1 HTTP 协议是无状态的
HTTP 协议不会记住用户身份,每一次请求对服务器来说都是 “陌生人”。
这会导致:
- 登录后刷新页面 → 又要重新登录
- 无法保存用户信息
- 无法实现购物车、权限判断、后台管理
1.2 会话控制是什么?
会话控制 = 让服务器记住当前用户。 从用户打开网站 → 登录 → 操作 → 关闭网站,整个过程保持登录状态,这就是会话控制。
1.3 Gin 中两种会话方案
- Cookie:数据存在浏览器(客户端)
- Session:数据存在服务器(服务端)
二、Cookie 超详细讲解(客户端存储)
2.1 什么是 Cookie?
- Cookie 是服务器写给浏览器的一小段文本数据
- 浏览器自动保存
- 下次请求同一网站时自动携带
- 键值对格式,有过期时间
- 大小限制约 4KB
- 不安全(可查看、可篡改)
2.2 Cookie 工作流程
- 浏览器请求服务器
- 服务器通过响应头返回
Set-Cookie - 浏览器保存 Cookie
- 下次请求自动在请求头带上 Cookie
- 服务器读取 Cookie 识别用户
2.3 Gin 中 Cookie 所有用法(逐行详解)
2.3.1 设置 Cookie(最全参数)
// 设置 Cookie
r.GET("/setCookie", func(c *gin.Context) {
/*
参数说明(共7个,必须记)
1. name Cookie 名称
2. value Cookie 值
3. maxAge 有效时间(秒) 60*60*24 = 1天
4. path 生效路径 / 表示全站有效
5. domain 域名 空表示当前域名
6. secure 是否仅HTTPS生效 false=http/https都可以
7. httpOnly 是否仅http可访问(true=JS无法读取,更安全)
*/
c.SetCookie("username", "Gin-Student", 60*60*24, "/", "", false, true)
c.String(200, "✅ Cookie 设置成功!名称:username,值:Gin-Student")
})
2.3.2 获取 Cookie
r.GET("/getCookie", func(c *gin.Context) {
// 根据名称获取 Cookie
username, err := c.Cookie("username")
// 判断是否获取成功
if err != nil {
c.String(200, "❌ 未找到 Cookie 或已过期")
return
}
c.String(200, "✅ 获取到Cookie:username = "+username)
})
2.3.3 删除 Cookie
原理:把有效时间设置为 -1,浏览器会自动删除
r.GET("/delCookie", func(c *gin.Context) {
// 参数必须和设置时一致(除了value和maxAge)
c.SetCookie("username", "", -1, "/", "", false, true)
c.String(200, "✅ Cookie 已删除")
})
2.4 Cookie 优点与缺点
优点:
- 简单、轻量
- 服务器无需存储
- 自动携带
缺点:
- 不安全(可查看、可篡改)
- 容量小(4KB)
- 受跨域限制
- 不能存敏感信息(密码、身份证)
三、Session 超详细讲解(服务端存储)
3.1 什么是 Session?
- Session 是服务器端的会话存储
- 每个用户拥有独立的 Session
- 基于 Cookie 实现(浏览器只存一个
sessionId) - 安全、容量大、适合存登录信息
3.2 Session 工作流程
- 登录成功
- 服务器创建 Session,保存用户信息
- 服务器返回
sessionId到浏览器 Cookie - 后续请求自动携带
sessionId - 服务器通过
sessionId找到对应用户信息
3.3 Gin 集成 Session(企业标准)
3.3.1 安装依赖
go get github.com/gin-contrib/sessions
go get github.com/gin-contrib/sessions/cookie
3.3.2 初始化 Session(必须写在最前面)
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
func main() {
// 1. 创建 Gin 路由
r := gin.Default()
// 2. 创建 Session 存储引擎(参数是密钥,必须写,用于加密)
store := cookie.NewStore([]byte("my-secret-key-123456789"))
// 3. 设置 Session 配置(可选,企业常用)
store.Options(sessions.Options{
MaxAge: 86400, // 有效期 1天(秒)
Path: "/", // 全路径生效
HttpOnly: true, // 禁止JS读取,安全
Secure: false, // 是否HTTPS
})
// 4. 注册 Session 中间件
// 参数1:Cookie 名称(自定义)
// 参数2:存储引擎
r.Use(sessions.Sessions("my-gin-session", store))
// ———————————— 路由写下面 ————————————
// 启动服务
r.Run(":8080")
}
四、Session 完整实战:登录、判断、拦截、退出
4.1 登录接口(设置 Session)
// 登录:验证账号密码,设置 Session
r.GET("/login", func(c *gin.Context) {
// 1. 获取前端传入的账号密码(真实项目用POST)
username := c.Query("username")
password := c.Query("password")
// 2. 模拟验证(真实项目查数据库)
if username == "admin" && password == "123456" {
// 3. 获取 Session 对象
s := sessions.Default(c)
// 4. 设置登录信息(可存任意多个)
s.Set("userId", 1001) // 用户ID
s.Set("username", username) // 用户名
s.Set("role", "admin") // 角色
// 5. 保存 Session(必须调用!)
s.Save()
c.JSON(200, gin.H{
"code": 200,
"message": "✅ 登录成功",
})
return
}
c.JSON(200, gin.H{
"code": 400,
"message": "❌ 账号或密码错误",
})
})
4.2 获取用户信息(判断是否登录)
// 获取当前登录用户信息
r.GET("/user/info", func(c *gin.Context) {
// 1. 获取 Session
s := sessions.Default(c)
// 2. 读取数据
userId := s.Get("userId")
username := s.Get("username")
role := s.Get("role")
// 3. 判断是否登录
if userId == nil {
c.JSON(200, gin.H{
"code": 401,
"message": "❌ 未登录,请先登录",
})
return
}
// 4. 返回用户信息
c.JSON(200, gin.H{
"code": 200,
"message": "✅ 获取成功",
"userId": userId,
"username": username,
"role": role,
})
})
4.3 退出登录(销毁 Session)
// 退出登录:清空 Session
r.GET("/logout", func(c *gin.Context) {
s := sessions.Default(c)
// 清空所有数据
s.Clear()
// 销毁 Session
s.Delete("userId")
s.Delete("username")
// 保存修改
s.Save()
c.JSON(200, gin.H{
"code": 200,
"message": "✅ 退出登录成功",
})
})
五、企业实战:登录拦截中间件(必学)
5.1 编写登录验证中间件
// 登录认证中间件:所有需要登录的接口必须经过这里
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 1. 获取 Session
s := sessions.Default(c)
userId := s.Get("userId")
// 2. 判断是否登录
if userId == nil {
// 返回JSON提示
c.JSON(200, gin.H{
"code": 401,
"message": "❌ 未登录,请先登录",
})
// 终止请求,不继续执行接口
c.Abort()
return
}
// 3. 已登录,放行
c.Next()
}
}
5.2 使用中间件保护接口
// 需要登录才能访问的路由组
authRouter := r.Group("/admin")
// 使用中间件
authRouter.Use(AuthMiddleware())
{
authRouter.GET("/dashboard", func(c *gin.Context) {
c.String(200, "✅ 后台首页(已登录)")
})
authRouter.GET("/user/list", func(c *gin.Context) {
c.String(200, "✅ 用户列表(已登录)")
})
}
六、Session 生命周期与安全配置(超详细)
6.1 设置 Session 有效期
store.Options(sessions.Options{
MaxAge: 86400, // 1天
Path: "/", // 生效路径
HttpOnly: true, // 禁止JS读取
Secure: false, // 生产环境改为true(HTTPS)
SameSite: http.SameSiteStrictMode, // 防CSRF攻击
})
6.2 Session 常用方法大全
s := sessions.Default(c)
// 设置
s.Set("key", value)
// 获取
s.Get("key")
// 删除
s.Delete("key")
// 清空全部
s.Clear()
// 保存(必须)
s.Save()
七、Cookie 与 Session 对比(面试必背)
| 对比项 | Cookie | Session |
|---|---|---|
| 存储位置 | 浏览器(客户端) | 服务器 |
| 安全性 | 低(可查看、可篡改) | 高(安全) |
| 存储大小 | 小(4KB) | 大(无限制) |
| 依赖 Cookie | 自身就是 Cookie | 依赖 Cookie 存 sessionId |
| 服务器压力 | 无 | 占用服务器内存 |
| 适用场景 | 记住账号、主题、非敏感数据 | 登录状态、权限、用户信息 |
八、企业开发最佳实践
- 登录状态必须用 Session,不要用 Cookie
- Cookie 只存非敏感信息
- Session 开启
HttpOnly防止 XSS - Session 有效期设置 1 天
- 所有后台接口必须使用登录拦截中间件
- 退出登录必须清空 Session
- 生产环境使用 HTTPS
九、完整可运行代码(复制即用)
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
// 登录中间件
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
s := sessions.Default(c)
userId := s.Get("userId")
if userId == nil {
c.JSON(200, gin.H{"code": 401, "msg": "未登录"})
c.Abort()
return
}
c.Next()
}
}
func main() {
r := gin.Default()
// Session 初始化
store := cookie.NewStore([]byte("secret123456"))
store.Options(sessions.Options{
MaxAge: 86400,
HttpOnly: true,
})
r.Use(sessions.Sessions("mysession", store))
// Cookie 示例
r.GET("/setCookie", func(c *gin.Context) {
c.SetCookie("username", "test", 60*60*24, "/", "", false, true)
c.String(200, "设置Cookie成功")
})
r.GET("/getCookie", func(c *gin.Context) {
val, _ := c.Cookie("username")
c.String(200, "获取到:"+val)
})
// Session 登录
r.GET("/login", func(c *gin.Context) {
s := sessions.Default(c)
s.Set("userId", 1001)
s.Set("username", "admin")
s.Save()
c.JSON(200, gin.H{"msg": "登录成功"})
})
// 获取信息
r.GET("/user/info", func(c *gin.Context) {
s := sessions.Default(c)
user := s.Get("username")
if user == nil {
c.JSON(200, gin.H{"msg": "未登录"})
return
}
c.JSON(200, gin.H{"user": user})
})
// 退出
r.GET("/logout", func(c *gin.Context) {
s := sessions.Default(c)
s.Clear()
s.Save()
c.JSON(200, gin.H{"msg": "退出成功"})
})
// 受保护路由
admin := r.Group("/admin")
admin.Use(AuthMiddleware())
{
admin.GET("/data", func(c *gin.Context) {
c.String(200, "敏感数据")
})
}
r.Run(":8080")
}
十、总结(超清晰)
- HTTP 无状态 → 必须用会话控制
- Cookie 存在浏览器,不安全,存少量数据
- Session 存在服务器,安全,适合登录
- Gin 使用
gin-contrib/sessions实现 Session - 登录流程:验证账号 → 设置 Session → 保存
- 中间件实现统一登录拦截
- 退出登录:清空 Session + 保存
- 企业开发:登录用 Session,普通配置用 Cookie
版权声明
本文为原创 Go 语言 Gin 会话控制 超详细教程,逐行讲解、无省略、无门槛、可直接用于课程实训、作业、面试、企业开发,禁止未经授权转载抄袭。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)