5

使用gin搭建api后台系统之cookie与session

 2 years ago
source link: https://www.yangyanxing.com/article/use-go-gin-cookie-session.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

之前的文章都是一种无状态的请求,在处理有状态的请求时,如用户登录的场景就不行了,web系统通常使用cookie或者session来记录用户状态,本文记录一下gin框架下cookie与session的使用。

读取cookie

gin.Context 里有个Cookie 方法,返回想要获取的cookie,如果不存在,则会返回一个错误 http: named cookie not present ,可以通过判断是否有这个错误来判断是否有相关的cookie。

func (ApiV1) Cookies(c *gin.Context) {
	cookie, err := c.Cookie("user")
	if err != nil{
		c.JSON(200, gin.H{"msg": err.Error()})
	}else{
		c.JSON(200, gin.H{"msg": cookie})
	}
}

设置cookie

可以使用SetCookie 方法来设置cookie,这个方法参数比较多

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

这些参数的意义如下

  • 第一个参数name 为 cookie 名;
  • 第二个参数value 为 cookie 值;
  • 第三个参数maxAge 为 cookie 有效时长,当 cookie 存在的时间超过设定时间时,cookie 就会失效,它就不再是我们有效的 cookie,他的时间单位是秒second;
  • 第四个参数path 为 cookie 所在的目录;
  • 第五个domain 为所在域,表示我们的 cookie 作用范围,里面可以是localhost也可以是你的域名,看自己情况;
  • 第六个secure 表示是否只能通过 https 访问,为true只能是https;
  • 第七个httpOnly 表示 cookie 是否可以通过 js代码进行操作,为true时不能被js获取
func (ApiV1) SetCookie(c *gin.Context)  {
	cookie, err := c.Cookie("user")
	if err != nil{
		c.SetCookie("user", "yangyanxing",3600, "/", "127.0.0.1",
			false, false)
		c.JSON(200, gin.H{"msg": "设置cookie成功"})
	}else{
		c.JSON(200, gin.H{"msg": cookie})
	}
}

删除cookie

没有一个方法可以直接删除cookie,但是可以通过设置有效期为负数来达到删除的目的

比如要删除掉user这个cookie,其实这时候它的值是多少已经无所谓了,可以设置个空

func (ApiV1) DelCookie(c *gin.Context)  {
	c.SetCookie("user", "", -1,"/", "127.0.01", false, false)
	c.String(200,"删除user cookie成功")
}

操作session

cookie 虽然很方便,但是它的安全性还是有些问题,客户端可以任意的做修改,这时也可以使用session 来存储状态。gin 框架本身不支持session,但是我们可以使用第三方库 https://github.com/gin-contrib/sessions 来操作session,这个session框架可以将信息存储在不同的地方

gin-contrib/sessions中间件支持的存储引擎:

  • cookie
  • memstore
  • redis
  • memcached
  • mongodb

使用cookie存储

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的存储引擎,yangyanxing 参数是用于加密的密钥
	store := cookie.NewStore([]byte("yangyanxing"))
	// 设置session中间件,参数mysession,指的是session的名字,也是cookie的名字
	// store是前面创建的存储引擎,我们可以替换成其他存储引擎
	r.Use(sessions.Sessions("mysession", store))
	apiv1_h := handlers.ApiV1{}
	apiv1 := r.Group("/api/v1")
	{
		apiv1.GET("/session/get", apiv1_h.GetSession)
		apiv1.GET("/session/set", apiv1_h.SetSession)

	}
	r.Run(":8080")
}

store := cookie.NewStore([]byte("yangyanxing")) 这行代码初始化一个存储引擎,参数为密钥,用于加解密

r.Use(sessions.Sessions("mysession", store)) 这是一个中间件,cookie就是以mysesson为name存储,store 为上面初始化的存储引擎。

在处理类中操作session

func (ApiV1) GetSession(c *gin.Context)  {
	session := sessions.Default(c)
	if value:= session.Get("user"); value==nil{
		c.String(200,"在session中没有user")
	}else{
		c.String(200, value.(string))
	}
}

func (receiver ApiV1) SetSession(c *gin.Context)  {
	session := sessions.Default(c)
	session.Set("user", "yangyanxing")
	err := session.Save()
	if err != nil {
		c.String(200, err.Error())
	}
	c.String(200, "设置session成功")
}

注意,对session进行写操作,如设置修改删除等,必须要调用session.Save() 方法,否则不能生效。

下图为在chrome中查看到的cookies信息。可以看到,value 是加密的

image-20220105224736107

也可以一次性全部清除

func (ApiV1) ClearSession(c *gin.Context)  {
	session := sessions.Default(c)
	//session.Delete("user")
	session.Clear()
	err := session.Save()
	if err != nil {
		c.String(200, err.Error())
		return
	}
	c.String(200, "清理成功")
}

Delete 为删除单个值,Clear 为清除所有,但是注意,即使使用了Clear,它只是清除了session中的信息,但是cookie中的mysession还是存在的,但是值是不一样了。

使用redis 存储 session

用法和cookie 一样,只是在初始化存储引擎的时候不一样

store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []**byte**("secret"))

  • 第1个参数 - redis最大的空闲连接数
  • 个参数 - 数通信协议tcp或者udp
  • 参数 - redis地址, 格式,host:port
  • 第4个参数 - redis密码
  • 第5个参数 - session加密密钥

注意:

使用 redis.NewStore 初始化的store 默认使用redis的db0, 更多的时候,我们会使用** redis.NewRediStoreWithDB** 来指定db

golang gin setcookie参数详解

https://github.com/gin-contrib/sessions

Gin框架如何处理session


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK