• Gin 中的 Session(会话控制)


    Session 介绍

    session和cookie实现的底层目标是一致的,但是从根本而言实现的方法是不同的

    session 是另一种记录客户状态的机制, 不同的是 Cookie 保存在客户端浏览器中,而 session保存 在服务器上

    Session 的工作流程

    当客户端浏览器第一次访问服务器并发送请求时,服务器端会创建一个 session 对象,生成一个类似于 key,value 的键值对, 然后将 value 保存到服务器,将 key(cookie)返回到浏览器(客户)端
    浏览器下次访问时会携带 key(cookie),找到对应的 session(value)。

    Gin 官方没有给我们提供 Session 相关的文档,这个时候我们可以使用第三方的 Session 中间件来实现;

     gin-contrib/sessions 中间件支持的存储引擎:

     cookie memstore redis memcached mongodb

    基于 Cookie 存储 Session 

    1、安装 session 包

    go get github.com/gin-contrib/sessions

    2、main.go入口文件引入session 

    密钥是成对定义的,以允许密钥循环,但常见的情况是设置一个身份验证密钥和一个加密密钥 (可选)。
    -对密钥中的第一个用于身份验证,第二个用于加密。加密密钥可以设置为零或在最后一对中省略,但所有对中都需要身份验证密钥。
    建议使用32或64字节的认证密钥。加密密钥 (如果设置) 必须是16,2424或32字节来选择AES-128、AES-192或AES-256模式。

    创建基于 cookie 的存储引擎,secret8090 参数是用于加密的密钥

    设置 session 中间件,参数 mysession,指的是 session 的名字,也是 cookie 的名字 

    store 是前面创建的存储引擎,可以替换成其他存储引擎

    1. package main
    2. import (
    3. "gindemo04/models"
    4. "gindemo04/routers"
    5. "github.com/gin-contrib/sessions"
    6. "github.com/gin-contrib/sessions/cookie"
    7. "github.com/gin-gonic/gin"
    8. "html/template"
    9. )
    10. func main() {
    11. // 创建一个默认的路由引擎
    12. r := gin.Default()
    13. //自定义模板函数 注意要把这个函数放在加载模板前
    14. r.SetFuncMap(template.FuncMap{
    15. "UnixToTime": models.UnixToTime,
    16. })
    17. //加载模板 放在配置路由前面
    18. r.LoadHTMLGlob("templates/**/*")
    19. //配置静态web目录 第一个参数表示路由, 第二个参数表示映射的目录
    20. r.Static("/static", "./static")
    21. // 创建基于 cookie 的存储引擎,secret8090 参数是用于加密的密钥
    22. //搞这个中间件先去上面import引入了,然后这里再配置
    23. store := cookie.NewStore([]byte("secret8090"))
    24. // 设置 session 中间件,参数 mysession,指的是 session 的名字,也是 cookie 的名字
    25. // store 是前面创建的存储引擎,可以替换成其他存储引擎
    26. r.Use(sessions.Sessions("mysession", store))
    27. routers.AdminRoutersInit(r)
    28. routers.ApiRoutersInit(r)
    29. routers.DefaultRouters(r)
    30. r.Run(":80")
    31. }

    3、控制器配置

    1. package test
    2. import (
    3. "fmt"
    4. "gindemo04/models"
    5. "net/http"
    6. "github.com/gin-contrib/sessions"
    7. "github.com/gin-gonic/gin"
    8. )
    9. type ModelTest struct{}
    10. func (con ModelTest) Index(c *gin.Context) {
    11. //设置sessions
    12. session := sessions.Default(c)
    13. session.Set("username","卫宫士郎")
    14. session.Save() //设置sessions的时候必须调用这个save
    15. fmt.Println(models.UnixToTime(1757814260))
    16. c.HTML(http.StatusOK, "default/index.html", gin.H{
    17. "msg": "session测试内容--转换时间戳---如下:",
    18. "t": 1757814260,
    19. })
    20. }
    21. func (con ModelTest) News(c *gin.Context) {
    22. //获取session
    23. session := sessions.Default(c)
    24. username := session.Get("username")
    25. c.String(http.StatusOK, "username=%v",username)
    26. }

     4、测试

    当客户端浏览器首次访问服务端,服务器端会创建一个 session 对象,生成一个类似于 key,value 的键值对,然后将 value 保存到服务器,将 key返下发到浏览器(客户)端,生成一个cookie

    再次访问的时候,携带上次的cookie也就是key去找value;

    那么有一个问题,生产环境使用的是nginx的负载均衡模式;

    如果访问nginx,写入到了一台服务器,那么其他服务器内没有session有的key以及value怎么办?

    那么就涉及到分布式环境,将session的kv保存到数据库内了

    Redis数据库保存session

     newstore后面需要跟的内容为:

    尺寸:最大空闲连接数。网络: 服务器地址:port password:redis-password密钥是成对定义的,以允许密钥轮换,但常见的情况是设置一个认证密钥和一个加密密钥 (可选)。
    -对密钥中的第一个用于身份验证,第二个用于加密。加密密钥可以设置为零或在最后一对中省略,但所有对中都需要身份验证密钥。
    建议使用32或64字节的身份验证密钥。加密密钥 (如果设置) 必须是16,2424或32字节来选择AES-128、AES-192或AES-256模式。

    1、main.go文件配置

    1. package main
    2. import (
    3. "gindemo04/models"
    4. "gindemo04/routers"
    5. "github.com/gin-contrib/sessions"
    6. "github.com/gin-contrib/sessions/redis"
    7. "github.com/gin-gonic/gin"
    8. "html/template"
    9. )
    10. func main() {
    11. // 创建一个默认的路由引擎
    12. r := gin.Default()
    13. //自定义模板函数 注意要把这个函数放在加载模板前
    14. r.SetFuncMap(template.FuncMap{
    15. "UnixToTime": models.UnixToTime,
    16. })
    17. //加载模板 放在配置路由前面
    18. r.LoadHTMLGlob("templates/**/*")
    19. //配置静态web目录 第一个参数表示路由, 第二个参数表示映射的目录
    20. r.Static("/static", "./static")
    21. // 这里需要修改存储引擎
    22. store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret8090"))
    23. r.Use(sessions.Sessions("mysession", store))
    24. routers.AdminRoutersInit(r)
    25. routers.ApiRoutersInit(r)
    26. routers.DefaultRouters(r)
    27. r.Run(":80")
    28. }

    2、控制器配置

    1. package test
    2. import (
    3. "fmt"
    4. "gindemo04/models"
    5. "net/http"
    6. "github.com/gin-contrib/sessions"
    7. "github.com/gin-gonic/gin"
    8. )
    9. type ModelTest struct{}
    10. func (con ModelTest) Index(c *gin.Context) {
    11. //设置sessions
    12. session := sessions.Default(c)
    13. session.Set("username","卫宫士郎")
    14. session.Save() //设置sessions的时候必须调用这个save
    15. fmt.Println(models.UnixToTime(1757814260))
    16. c.HTML(http.StatusOK, "default/index.html", gin.H{
    17. "msg": "session测试内容--转换时间戳---如下:",
    18. "t": 1757814260,
    19. })
    20. }
    21. func (con ModelTest) News(c *gin.Context) {
    22. //获取session
    23. session := sessions.Default(c)
    24. username := session.Get("username")
    25. c.String(http.StatusOK, "username=%v",username)
    26. }

    3、配置完成redis,打开cmd

    输入redis-cli查看是否安装成功

     4、查看redis是否有键值对

    5、运行我们的seesion,把v上传服务器

    再访问news

    查看redis是否保存value(cookie)

    进行加密后的

    session的过期时间配置

    查看session的配置options的结构体内,有过期时间的配置

    MaxAge的单位是秒

    在控制器的set上面进行操作:

    1. func (con ModelTest) Index(c *gin.Context) {
    2. //设置sessions
    3. session := sessions.Default(c)
    4. session.Options(sessions.Options{
    5. MaxAge: 3600 * 6 ,
    6. })
    7. session.Set("username","卫宫士郎")
    8. session.Save() //设置sessions的时候必须调用这个save
    9. fmt.Println(models.UnixToTime(1757814260))
    10. c.HTML(http.StatusOK, "default/index.html", gin.H{
    11. "msg": "session测试内容--转换时间戳---如下:",
    12. "t": 1757814260,
    13. })
    14. }

  • 相关阅读:
    【校招VIP】前端操作系统之进程与线程
    第一个 Python 程序
    2020年江西省职业院校技能大赛高职组“信息安全管理与评估”赛项任务书样题
    【数据结构与算法】之深入解析“两个盒子中球的颜色数相同的概率”的求解思路与算法示例
    头条系统-05-延迟队列精准发布文章-概述&添加任务(db和redis实现延迟任务)、取消&拉取任务&定时刷新(redis管道、分布式锁setNx)
    Git操作复习笔记
    Spring中@Lazy注解的使用
    【HTML期末作业】大学生抗疫感动专题网页设计作业 抗疫最美逆行者网页 致敬疫情感动人物网页设计制作
    Runaway Queries 管理:提升 TiDB 稳定性的智能引擎
    货币银行学重点汇总
  • 原文地址:https://blog.csdn.net/m0_72264240/article/details/133793215