第31讲 Gin登录后获取session
本讲基于视频实际讲解内容整理
一、本讲概述
HTTP 是无状态协议,服务器默认记不住"你是谁"。登录功能需要**会话(Session)**来保存登录状态。本讲讲解在 Gin 中使用 gin-contrib/sessions 中间件:登录成功后写入 Session,后续请求读取 Session 判断用户是否已登录。
二、安装 session 中间件
Shell
go get github.com/gin-contrib/sessions
三、注册 session 中间件
3.1 基于 Cookie 的存储
Go
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 用密钥创建 cookie 存储
store := cookie.NewStore([]byte("secret-key-123"))
// 注册中间件,session 名为 "mysession"
r.Use(sessions.Sessions("mysession", store))
// ... 路由
r.Run(":8080")
}
| 要素 | 说明 |
|---|---|
[]byte("secret-key") |
用于加密/签名 cookie 的密钥,生产要换成复杂随机值 |
"mysession" |
session 在 cookie 里的名字 |
r.Use(...) |
让每个请求都能访问 session |
老师强调:密钥不能太简单,否则 session 可能被伪造。这只是 cookie 存储,数据存在客户端 cookie 中(已加密签名)。
四、登录时写入 Session
4.1 设置 session 值
Go
func Login(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
// 这里省略真实的账号校验,假设校验通过
session := sessions.Default(c)
session.Set("username", username) // 写入用户名
session.Save() // 必须 Save 才生效
c.JSON(200, gin.H{"msg": "登录成功"})
}
关键点:
session.Save()必须调用,否则写入不会真正保存。这是初学者最容易漏的一步。
五、获取 Session(判断登录状态)
5.1 读取 session 值
Go
func Index(c *gin.Context) {
session := sessions.Default(c)
username := session.Get("username") // 返回 interface{}
if username == nil {
// 没登录,跳转到登录页
c.Redirect(302, "/login")
return
}
c.HTML(200, "index.html", gin.H{
"username": username.(string),
})
}
老师说明:
session.Get返回的是interface{},可能为nil(未登录)。取值后通常需要类型断言成string。
5.2 用中间件统一校验登录
把"判断是否登录"抽成中间件,避免每个 handler 都写一遍:
Go
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
session := sessions.Default(c)
if session.Get("username") == nil {
c.Redirect(302, "/login")
c.Abort() // 阻止继续往下执行
return
}
c.Next()
}
}
Go
// 需要登录的路由加上该中间件
r.GET("/post/new", AuthRequired(), controller.NewPostPage)
老师强调:
c.Abort()很关键,校验不通过时要立刻中断,否则 handler 还会继续执行。
六、退出登录(销毁 Session)
Go
func Logout(c *gin.Context) {
session := sessions.Default(c)
session.Delete("username") // 删除指定键
// 或 session.Clear() 清空全部
session.Save()
c.Redirect(302, "/login")
}
七、本讲小结
| 知识点 | 要点 |
|---|---|
| 安装 | gin-contrib/sessions |
| 注册 | r.Use(sessions.Sessions("名", store)) |
| 写入 | session.Set("k", v); session.Save() |
| 读取 | session.Get("k")(返回 interface{}) |
| 必须 Save | 不 Save 不生效 |
| 登录校验 | 抽成中间件 + c.Abort() |
| 退出 | session.Delete / Clear + Save |
八、课后练习
- 安装
gin-contrib/sessions,在main中注册 cookie 存储中间件 - 在
Login中校验通过后写入username到 session 并Save() - 在
Index中读取 session,未登录则跳转到/login - 写一个
AuthRequired中间件,保护"发帖"等需要登录的路由 - 实现"退出登录":删除 session 中的 username 并跳转
- 思考:cookie 存储和把 session 存到 Redis 各有什么优缺点?