Gin框架的Cookie与session案例
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.Cookie与session概述
1>.cookie和session的产生背景
由于HTTP协议是无状态的,服务器无法确定这次请求和上次请求是否来自同一个客户端。就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
利用session和cookie可以让服务器直到不同的请求是否来自同一个客户端。
2>.Cookie与session的区别
什么是Cookie: Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。 Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。 客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。 什么是Session: 除了使用Cookie,Web应用程序中还经常使用Session来记录客户端状态。Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。 Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。 客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。 cookie和session的区别: 1>.cookie数据存放在客户的浏览器上,session数据放在服务器上(可以放在文件,数据库或者内存都可以); 2>.cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session; 3>.两者最大的区别在于生存周期,一个是IE启动到IE关闭.(浏览器页面一关 ,session就消失了),一个是预先设置的生存周期,或永久的保存于本地的文件。(cookie) 4>.session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie; 5>.单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型); 综上所述,如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。 温馨提示: Session信息是存放在server端,但session id是存放在client cookie的
3>.安装session插件
go get github.com/gin-contrib/sessions
二.Cookie与session案例
1>.cookie案例
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { /** 所有的接口都要由路由来进行管理。 Gin的路由支持GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS等请求 同时还有一个Any函数,可以同时支持以上的所有请求。 创建路由(router)并引入默认中间件 router := gin.Default() 在源码中,首先是New一个engine,紧接着通过Use方法传入了Logger()和Recovery()这两个中间件。 其中 Logger 是对日志进行记录,而 Recovery 是对有 painc时, 进行500的错误处理。 创建路由(router)无中间件 router := gin.New() */ router := gin.Default() router.GET("/cookie", func(context *gin.Context) { //获取Cookie cookie, err := context.Cookie("gin_cookie") if err != nil { cookie = "NotSet" //设置cookie context.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true) } fmt.Println("cookie value: ", cookie) }) //启动路由并指定监听的地址及端口,若不指定默认监听0.0.0.0:8080 router.Run("172.30.100.101:9000") /** 使用curl命令测试: [root@yinzhengjie.com ~]# curl -v http://172.30.100.101:9000/cookie */ }
2>.session案例
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" "net/http" ) func main() { /** 所有的接口都要由路由来进行管理。 Gin的路由支持GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS等请求 同时还有一个Any函数,可以同时支持以上的所有请求。 创建路由(router)并引入默认中间件 router := gin.Default() 在源码中,首先是New一个engine,紧接着通过Use方法传入了Logger()和Recovery()这两个中间件。 其中 Logger 是对日志进行记录,而 Recovery 是对有 painc时, 进行500的错误处理。 创建路由(router)无中间件 router := gin.New() */ router := gin.Default() //定义加密 store := cookie.NewStore([]byte("secret")) //绑定session中间件 router.Use(sessions.Sessions("mysession", store)) //定义GET方法 router.GET("/session", func(context *gin.Context) { //初始化session对象 session := sessions.Default(context) //如果浏览器第一次访问返回状态码401,第二次访问则返回状态码200 if session.Get("user") != "yinzhengjie" { session.Set("user", "yinzhengjie") session.Save() context.JSON(http.StatusUnauthorized, gin.H{"user": session.Get("user")}) } else { context.String(http.StatusOK, "Successful second visit") } }) //启动路由并指定监听的地址及端口,若不指定默认监听0.0.0.0:8080 router.Run("172.30.100.101:9000") /** 测试工具建议使用浏览器访问"http://172.30.100.101:9000/session“,不推荐使用curl命令。 因为curl工具无法缓存,浏览器是由缓存的可以很明显看到测试效果。 */ }
3>.将session存储在Redis服务器案例
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package main import ( "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/redis" "github.com/gin-gonic/gin" "net/http" ) func main() { /** 所有的接口都要由路由来进行管理。 Gin的路由支持GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS等请求 同时还有一个Any函数,可以同时支持以上的所有请求。 创建路由(router)并引入默认中间件 router := gin.Default() 在源码中,首先是New一个engine,紧接着通过Use方法传入了Logger()和Recovery()这两个中间件。 其中 Logger 是对日志进行记录,而 Recovery 是对有 painc时, 进行500的错误处理。 创建路由(router)无中间件 router := gin.New() */ router := gin.Default() //定义加密(将session信息存储在redis服务器) store, _ := redis.NewStore(10, "tcp", "172.200.1.254:6379", "", []byte("secret")) //绑定session中间件 router.Use(sessions.Sessions("mySession", store)) //定义GET方法 router.GET("/session", func(context *gin.Context) { //初始化session对象 session := sessions.Default(context) //如果浏览器第一次访问返回状态码401,第二次访问则返回状态码200 if session.Get("user") != "yinzhengjie" { session.Set("user", "yinzhengjie") session.Save() context.JSON(http.StatusUnauthorized, gin.H{"user": session.Get("user")}) } else { context.String(http.StatusOK, "Successful second visit") } }) //启动路由并指定监听的地址及端口,若不指定默认监听0.0.0.0:8080 router.Run("172.30.100.101:9000") }