HTTP 是无状态协议,即请求的时候,浏览器和服务器是连接的,但是请求结束之后,连接就断了,这样的无状态协议,可以减轻服务器的压力。每一次的访问,都是没有任何关系的。如果想要实现多个页面之间共享数据的话可以使用 Cookie 或者 Session 实现。
Cookie 是存储在访问者计算机的浏览器当中,可以让我们用同一个浏览器访问同一个域名的时候共享数据。
设置 Cookie
c.SetCookie(name,value string, maxAge int, path,domain string, secure,httpOnly bool)
第一个参数 key
第二个参数 value
第三个参数 过期时间,如果只想设置 Cookie 的保存路径而不想设置存活时间,可以在第三个参数中传递 nil
第四个参数 cookie 的路径
第五个参数 cookie 的路径 Domain 作用域 本地调试配置成 localhost ,正式上线配置成域名
第六个参数 secure,当 secure 值为 true 时,cookie 在 HTTP 当中是无效的,在 HTTPS 当中才有效
第七个参数 httpOnly,是微软对 Cookie 做的扩展。如果在 Cookie 中设置了 “httpOnly” 属性,则通过程序(JS 脚本等)将无法读取到 Cookie 信息,防止 XSS 攻击产生
获取 Cookie
cookie,err := c.Cookie("name")
r.GET("/setCookie", func(c *gin.Context) {
c.SetCookie("username", "zhangsan", 3600, "/", "localhost", false, true)
c.String(http.StatusOK, "setCookie")
})
r.GET("/getCookie", func(c *gin.Context) {
cookie, err := c.Cookie("username")
if err == nil {
c.String(http.StatusOK, "Cookie="+cookie)
}
})
r.GET("/deleteCookie", func(c *gin.Context) {
c.SetCookie("username", "zhangsan", -1, "/", "localhost", false, false)
c.String(200, "删除Cookie")
})
session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。
当客户端浏览器第一次访问服务器并发送请求时,服务器端会创建一个 Session 对象,生成一个类似于 key, value的键值对,然后将 value 保存到服务器,将key(cookie)返回到浏览器(客户端),浏览器下次访问时会携带 key(cookie),找到对应的 session(value)。
Gin 官方并没有提供 Session 相关的文档,可以使用第三方的 Session 中间件来实现。
https://github.com/gin-contrib/sessions
1、安装 session 包
go get github.com/gin-contrib/sessions
2、基本的 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 的存储引擎,secret11111 参数是用于加密的密钥
store := cookie.NewStore([]byte("secret11111"))
// 设置 session 中间件,参数 mysession,指的是 session 的名字,也是 cookie 的名字
// store 是前面创建的存储引擎,我们可以替换成其他存储引擎
r.Use(sessions.Sessions("mysession", store))
r.GET("/", func(c *gin.Context) {
//初始化 session 对象
session := sessions.Default(c)
//设置过期时间
session.Options(sessions.Options{
MaxAge: 3600 * 6, // 6hrs
})
//设置 Session
session.Set("username", "张三")
session.Save()
c.JSON(200, gin.H{"msg": session.Get("username")})
})
r.GET("/user", func(c *gin.Context) {
// 初始化 session 对象
session := sessions.Default(c)
// 通过 session.Get 读取 session 值
username := session.Get("username")
c.JSON(200, gin.H{"username": username})
})
r.Run(":8000")
}
如果想将 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("/", func(c *gin.Context) {
session := sessions.Default(c)
session.Set("username", "李四")
session.Save()
c.JSON(200, gin.H{"username": session.Get("username")})
})
r.GET("/user", func(c *gin.Context) {
// 初始化 session 对象
session := sessions.Default(c)
// 通过 session.Get 读取 session 值
username := session.Get("username")
c.JSON(200, gin.H{"username": username})
})
r.Run(":8000")
}