Gin中的Session
1 Session简单介绍
session 是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而session保存在服务器上。
2 Session的工作流程
当客户端浏览器第一次访问服务器并发送请求时,服务器端会创建一个session对象,生成一个类似于key,value的键值对,然后将 value保存到服务器 将Key(cookie)返回到浏览器(客户端)。浏览器下次访问时会携带key(cookie),找到对应的session(value)
3 Gin中使用Session
Gin官方没有给我们提供Session相关的文档,这个时候我们可以使用第三方的Session中间件来实现
https://github.com/gin-contrib/sessions
gin-contrib/sessions 中间件支持的存储引擎:
cookie
memstore
redis
memcached
mongodb
4 基于Cookie存储Session
package main
import (
  "github.com/gin-contrib/sessions"      //引入
  "github.com/gin-contrib/sessions/cookie" //引入
  "github.com/gin-gonic/gin"
)
func main() {
  r := gin.Default()
  // 创建一个基于cookie的存储引擎 secret是用于加密的密钥可以随意更改
  store := cookie.NewStore([]byte("secret"))
  // 配置中间件 store 是前面创建的存储引擎,我们可以替换成其他存储引擎
  // mysession 是客户端中cookie的key 可以更改
  r.Use(sessions.Sessions("mysession", store))
  r.GET("/incr", func(c *gin.Context) {
    // 获取一个session对象 传入c
    session := sessions.Default(c)
    var count int
    // 获取session
    v := session.Get("count")
    if v == nil {
      count = 0
    } else {
      count = v.(int)
      count++
    }
    // 设置session
    session.Set("count", count)
    // 必须调用 才能保存
    session.Save()
    c.JSON(200, gin.H{"count": count})
  })
  r.Run(":8000")
}
5 基于redis实现分布式Session (只需要改变一下存储引擎,改为redis)
package main
import (
  "github.com/gin-contrib/sessions"       // 引入
  "github.com/gin-contrib/sessions/redis" // 引入
  "github.com/gin-gonic/gin"
)
func main() {
  r := gin.Default()
  // 创建一个基于redis的存储引擎 secret是用于加密的密钥可以随意更改
  store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
  // 配置中间件 store 是前面创建的存储引擎,我们可以替换成其他存储引擎
  // mysession 是客户端中cookie的key 可以更改
  r.Use(sessions.Sessions("mysession", store))
  r.GET("/incr", func(c *gin.Context) {
    // 获取一个session对象 传入c
    session := sessions.Default(c)
    var count int
    v := session.Get("count")
    if v == nil {
      count = 0
    } else {
      count = v.(int)
      count++
    }
    session.Set("count", count)
    session.Save()
    c.JSON(200, gin.H{"count": count})
  })
  r.Run(":8000")
}
/*
	store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
	
	第一个参数 size 连接数
	第二个参数 network 网络
	第三个参数 address 地址
	第四个参数 password 密码
	第五个参数 keyPairs 用于加密的密钥
*/
6 设置Session的过期时间
package main
import (
  "github.com/gin-contrib/sessions"       // 引入
  "github.com/gin-contrib/sessions/redis" // 引入
  "github.com/gin-gonic/gin"
)
func main() {
  r := gin.Default()
  // 创建一个基于redis的存储引擎 secret是用于加密的密钥可以随意更改
  store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
  // 配置中间件 store 是前面创建的存储引擎,我们可以替换成其他存储引擎
  // mysession 是客户端中cookie的key 可以更改
  r.Use(sessions.Sessions("mysession", store))
  r.GET("/incr", func(c *gin.Context) {
    // 获取一个session对象 传入c
    session := sessions.Default(c)
    // 配置过期时间
    session.Options(session.Options{
        MaxAge : 3600 * 6 // 6小时 单位是秒 默认是30天      
    })
      
    var count int
    v := session.Get("count")
    if v == nil {
      count = 0
    } else {
      count = v.(int)
      count++
    }
    session.Set("count", count)
    session.Save()
    c.JSON(200, gin.H{"count": count})
  })
  r.Run(":8000")
}