session和cookie实现的底层目标是一致的,但是从根本而言实现的方法是不同的;
Gin 官方没有给我们提供 Session 相关的文档,这个时候我们可以使用第三方的 Session 中间件来实现;
gin-contrib/sessions 中间件支持的存储引擎:
cookie memstore redis memcached mongodb
go get github.com/gin-contrib/sessions
密钥是成对定义的,以允许密钥循环,但常见的情况是设置一个身份验证密钥和一个加密密钥 (可选)。
-对密钥中的第一个用于身份验证,第二个用于加密。加密密钥可以设置为零或在最后一对中省略,但所有对中都需要身份验证密钥。
建议使用32或64字节的认证密钥。加密密钥 (如果设置) 必须是16,2424或32字节来选择AES-128、AES-192或AES-256模式。
创建基于 cookie 的存储引擎,secret8090 参数是用于加密的密钥
设置 session 中间件,参数 mysession,指的是 session 的名字,也是 cookie 的名字
store 是前面创建的存储引擎,可以替换成其他存储引擎
- package main
-
- import (
- "gindemo04/models"
- "gindemo04/routers"
- "github.com/gin-contrib/sessions"
- "github.com/gin-contrib/sessions/cookie"
- "github.com/gin-gonic/gin"
- "html/template"
- )
-
- func main() {
- // 创建一个默认的路由引擎
- r := gin.Default()
- //自定义模板函数 注意要把这个函数放在加载模板前
- r.SetFuncMap(template.FuncMap{
- "UnixToTime": models.UnixToTime,
- })
- //加载模板 放在配置路由前面
- r.LoadHTMLGlob("templates/**/*")
- //配置静态web目录 第一个参数表示路由, 第二个参数表示映射的目录
- r.Static("/static", "./static")
- // 创建基于 cookie 的存储引擎,secret8090 参数是用于加密的密钥
- //搞这个中间件先去上面import引入了,然后这里再配置
- store := cookie.NewStore([]byte("secret8090"))
- // 设置 session 中间件,参数 mysession,指的是 session 的名字,也是 cookie 的名字
- // store 是前面创建的存储引擎,可以替换成其他存储引擎
- r.Use(sessions.Sessions("mysession", store))
- routers.AdminRoutersInit(r)
-
- routers.ApiRoutersInit(r)
-
- routers.DefaultRouters(r)
-
- r.Run(":80")
- }
- package test
-
- import (
- "fmt"
- "gindemo04/models"
- "net/http"
-
- "github.com/gin-contrib/sessions"
- "github.com/gin-gonic/gin"
- )
-
- type ModelTest struct{}
-
- func (con ModelTest) Index(c *gin.Context) {
- //设置sessions
- session := sessions.Default(c)
- session.Set("username","卫宫士郎")
- session.Save() //设置sessions的时候必须调用这个save
- fmt.Println(models.UnixToTime(1757814260))
- c.HTML(http.StatusOK, "default/index.html", gin.H{
- "msg": "session测试内容--转换时间戳---如下:",
- "t": 1757814260,
- })
- }
- func (con ModelTest) News(c *gin.Context) {
- //获取session
- session := sessions.Default(c)
- username := session.Get("username")
- c.String(http.StatusOK, "username=%v",username)
- }
-
当客户端浏览器首次访问服务端,服务器端会创建一个 session 对象,生成一个类似于 key,value 的键值对,然后将 value 保存到服务器,将 key返下发到浏览器(客户)端,生成一个cookie
再次访问的时候,携带上次的cookie也就是key去找value;
那么有一个问题,生产环境使用的是nginx的负载均衡模式;
如果访问nginx,写入到了一台服务器,那么其他服务器内没有session有的key以及value怎么办?
那么就涉及到分布式环境,将session的kv保存到数据库内了
newstore后面需要跟的内容为:
尺寸:最大空闲连接数。网络: 服务器地址:port password:redis-password密钥是成对定义的,以允许密钥轮换,但常见的情况是设置一个认证密钥和一个加密密钥 (可选)。
-对密钥中的第一个用于身份验证,第二个用于加密。加密密钥可以设置为零或在最后一对中省略,但所有对中都需要身份验证密钥。
建议使用32或64字节的身份验证密钥。加密密钥 (如果设置) 必须是16,2424或32字节来选择AES-128、AES-192或AES-256模式。
- package main
-
- import (
- "gindemo04/models"
- "gindemo04/routers"
- "github.com/gin-contrib/sessions"
- "github.com/gin-contrib/sessions/redis"
- "github.com/gin-gonic/gin"
- "html/template"
- )
-
- func main() {
- // 创建一个默认的路由引擎
- r := gin.Default()
- //自定义模板函数 注意要把这个函数放在加载模板前
- r.SetFuncMap(template.FuncMap{
- "UnixToTime": models.UnixToTime,
- })
- //加载模板 放在配置路由前面
- r.LoadHTMLGlob("templates/**/*")
- //配置静态web目录 第一个参数表示路由, 第二个参数表示映射的目录
- r.Static("/static", "./static")
- // 这里需要修改存储引擎
- store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret8090"))
- r.Use(sessions.Sessions("mysession", store))
- routers.AdminRoutersInit(r)
-
- routers.ApiRoutersInit(r)
-
- routers.DefaultRouters(r)
-
- r.Run(":80")
- }
- package test
-
- import (
- "fmt"
- "gindemo04/models"
- "net/http"
-
- "github.com/gin-contrib/sessions"
- "github.com/gin-gonic/gin"
- )
-
- type ModelTest struct{}
-
- func (con ModelTest) Index(c *gin.Context) {
- //设置sessions
- session := sessions.Default(c)
- session.Set("username","卫宫士郎")
- session.Save() //设置sessions的时候必须调用这个save
- fmt.Println(models.UnixToTime(1757814260))
- c.HTML(http.StatusOK, "default/index.html", gin.H{
- "msg": "session测试内容--转换时间戳---如下:",
- "t": 1757814260,
- })
- }
- func (con ModelTest) News(c *gin.Context) {
- //获取session
- session := sessions.Default(c)
- username := session.Get("username")
- c.String(http.StatusOK, "username=%v",username)
- }
-
输入redis-cli查看是否安装成功
进行加密后的
查看session的配置options的结构体内,有过期时间的配置
MaxAge的单位是秒
在控制器的set上面进行操作:
- func (con ModelTest) Index(c *gin.Context) {
- //设置sessions
- session := sessions.Default(c)
- session.Options(sessions.Options{
- MaxAge: 3600 * 6 ,
- })
- session.Set("username","卫宫士郎")
- session.Save() //设置sessions的时候必须调用这个save
- fmt.Println(models.UnixToTime(1757814260))
- c.HTML(http.StatusOK, "default/index.html", gin.H{
- "msg": "session测试内容--转换时间戳---如下:",
- "t": 1757814260,
- })
- }