go框架(6)-gin会话

会话

会话控制涉及到cookie和session的使用

  1. HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否由同一个客户端发出

  2. Cookie就是解决HTTP协议无状态的方案之一

  3. Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该信息处理请求

  4. Cookie由服务器创建,并发送给浏览器,最终由浏览器保存

1.1 设置cookie

func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)

参数说明:

参数名

类型

说明

name

string

cookie名字

value

string

cookie值

maxAge

int

有效时间,单位是秒,MaxAge=0 忽略MaxAge属性,MaxAge<0 相当于删除cookie, 通常可以设置-1代表删除,MaxAge>0 多少秒后cookie失效

path

string

cookie路径

domain

string

cookie作用域

secure

bool

Secure=true,那么这个cookie只能用https协议发送给服务器

httpOnly

bool

设置HttpOnly=true的cookie不能被js获取到

r.GET("/cookie", func(c *gin.Context) {
  // 设置cookie
  c.SetCookie("site_cookie", "cookievalue", 3600, "/", "localhost", false, true)
 })

1.2 读取cookie

r.GET("/read", func(c *gin.Context) {
  // 根据cookie名字读取cookie值
  data, err := c.Cookie("site_cookie")
  if err != nil {
   // 直接返回cookie值
   c.String(200,data)
   return
  }
  c.String(200,"not found!")
 })

1.3 删除cookie

通过将cookie的MaxAge设置为-1, 达到删除cookie的目的。

r.GET("/del", func(c *gin.Context) {
  // 设置cookie  MaxAge设置为-1,表示删除cookie
  c.SetCookie("site_cookie", "cookievalue", -1, "/", "localhost", false, true)
  c.String(200,"删除cookie")
 })

2. Session

在Gin框架中,我们可以依赖gin-contrib/sessions中间件处理session。

安装session包

go get github.com/gin-contrib/sessions
package main

import (
 "fmt"
 "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"))
 // 设置session中间件,参数mysession,指的是session的名字,也是cookie的名字
 // store是前面创建的存储引擎,我们可以替换成其他存储引擎
 r.Use(sessions.Sessions("mysession", store))

 r.GET("/hello", func(c *gin.Context) {
  // 初始化session对象
  session := sessions.Default(c)
  // 通过session.Get读取session值
  // session是键值对格式数据,因此需要通过key查询数据
  if session.Get("hello") != "world" {
   fmt.Println("没读到")
   // 设置session数据
   session.Set("hello", "world")
   session.Save()
  }
  c.JSON(200, gin.H{"hello": session.Get("hello")})
 })
 r.Run(":8080")
}

2.1 多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()
 store := cookie.NewStore([]byte("secret"))
 sessionNames := []string{"a", "b"}
 r.Use(sessions.SessionsMany(sessionNames, store))

 r.GET("/hello", func(c *gin.Context) {
  sessionA := sessions.DefaultMany(c, "a")
  sessionB := sessions.DefaultMany(c, "b")

  if sessionA.Get("hello") != "world!" {
   sessionA.Set("hello", "world!")
   sessionA.Save()
  }

  if sessionB.Get("hello") != "world?" {
   sessionB.Set("hello", "world?")
   sessionB.Save()
  }

  c.JSON(200, gin.H{
   "a": sessionA.Get("hello"),
   "b": sessionB.Get("hello"),
  })
 })
 r.Run(":8080")
}

2.2 基于redis存储引擎的session

如果我们想将session数据保存到redis中,只要将session的存储引擎改成redis即可。

使用redis作为存储引擎的例子:

首先安装redis存储引擎的包

go get github.com/gin-contrib/sessions/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的存储引擎
 // 参数说明:
 //    第1个参数 - redis最大的空闲连接数
 //    第2个参数 - 数通信协议tcp或者udp
 //    第3个参数 - redis地址, 格式,host:port
 //    第4个参数 - redis密码
 //    第5个参数 - session加密密钥
 store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
 r.Use(sessions.Sessions("mysession", store))

 r.GET("/incr", func(c *gin.Context) {
  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(":8080")
}


go框架(6)-gin会话
http://47.123.5.226:8090//archives/gokuang-jia-6--ginhui-hua
作者
pony
发布于
2024年05月09日
许可协议