使用Session
我们知道HTTP协议是无状态的,但设计了Session机制可以实现保存一些状态信息。Session的实现方式有很多种,例如最为常见的方式是使用一个SessionId作为Cookie由客户端保存,而服务端则由内存或是数据库等方式保存一个Key-Value信息,Key即SessionId,Value即具体的Session数据,此外还有JWT等实现方式。
由于Session的实现方式各不相同,Gin框架本体没有对Session进行支持,而是通过扩展的方式,我们可以自己选择需要的库或是手动编写代码逻辑来实现Session。gin-contrib/sessions实现了几种常见的Session,如基于内存保存Session、基于Redis保存Session,基于MongoDB保存Session等。
项目Github地址:https://github.com/gin-contrib/sessions
安装Session扩展
我们可以指定下面命令安装Session扩展。
go get -u github.com/gin-contrib/sessions
go get -u github.com/gin-contrib/sessions/memstore
这里memstore是基于内存的Session,如果我们需要使用其它的Session后端如Redis等,参考官方文档的说明安装对应的包即可。
基于内存的Session
gin-contrib/sessions/memstore实现了基于内存的Session机制,这里我们简单学习一下其用法。
package main
import (
"fmt"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/memstore"
"github.com/gin-gonic/gin"
)
func main() {
engine := gin.Default()
// 设置Session存储
store := memstore.NewStore([]byte("secret"))
// 设置Session中间件
engine.Use(sessions.Sessions("session", store))
engine.GET("/login", func(context *gin.Context) {
session := sessions.Default(context)
session.Set("isLogin", true)
err := session.Save()
if err != nil {
fmt.Println(err)
return
}
})
engine.GET("/isLogin", func(context *gin.Context) {
session := sessions.Default(context)
context.JSON(200, gin.H{
"isLogin": session.Get("isLogin"),
})
})
err := engine.Run(":8080")
if err != nil {
fmt.Println(err)
return
}
}
在工程初始化时,我们首先创建了一个Store对象,它可以理解为对Session存储后端的一个抽象,NewStore()方法是参数是一个[]byte数组,它是Session数据的加密密钥。创建好Store后,我们给Gin设置了一个中间件,它用于处理Session的关联Cookie。后面代码我们实现了一个简单的登录和查看登录状态接口,注意设置Session后,不要忘了调用session.Save()保存,否则设置的Session是不会生效的。
对于其它类型的存储后端如Redis等,用法基本是类似的,参考对应的文档即可,这里就不赘述了。