go(gin框架)session底层使用redis实现(gorilla/sessions和gin-contrib/sessions)
问题描述
最近在写一个基于gin框架的demo,需要实现简单的rbac,在网上找了一个有基础功能的基本框架,Go Gin Example,框架本身集成了基本功能:日志,mysql增删改查,路由,jwt认证等功能,在这个基础上,首先实现rbac。
考虑到redis做缓存比较好管理、文档丰富,且我和公司同事都有丰富的使用经验,且上一个项目就是使用的redis做session,因此尽量还是用redis。
在网上和chatGpt搜索,发现几乎没有立即可用的方案,都云里雾里的,感觉参考价值不高,因此自己看文档研究。
工具调研
目前市面上比较常用的go语言使用session(尤其是gin框架)工具包有:gin-contrib/sessions和gorilla/sessions.
gin-contrib/sessions使用
设置session
gin默认的工具就是gin-contrib/sessions,因此首先来看gin-contrib/sessions怎么使用
查阅文档,发现官方是有默认redis支持的,copy过来改一改。发现没有自动把session id给设置到cookie中,可能需要手动设置。
// SetUserSession 设置用户session
func SetUserSession(c *gin.Context, userRet *User) {gob.Register(&User{})session := sessions.Default(c)session.Set("user-data", userRet)session.Save()sessionId := session.ID()// 在这之前,需要先清除已有的cookie和sessionuserRet.LogOut(c)middleware.SetCookie(c, "GOSESSID", "session_"+sessionId, 4*3600)
}
这里有个需要注意的点,获取sessionId需要在session.Save()执行之后,否则获取不到
middleware.SetCookie的作用是,设置一个名为GOSESSID
的cookie,值为"session_"+sessionId
。在各个请求中都能拿到这个cookie,进而去session中查询登录信息。
清除session
退出登录时,只需要获取到GOSESSID
的cookie内容,找到session的id(在redis中直接使用key存储),先清除session,再删除cookie
// LogOut 登出
func (u *User) LogOut(c *gin.Context) error {redisKeyName, err := c.Cookie("GOSESSID")if err != nil {return err}gredis.Delete(redisKeyName)middleware.ClearCookie(c, "GOSESSID", redisKeyName)return nil
}
gorilla/sessions 使用
设置session
以下是设置缓存的代码(包含校验用户信息):
var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))
// CheckUser 校验用户信息
func CheckUser(c *gin.Context, userName string, password string) error {checkPassCompare, err := hashPassword(password)if err != nil {c.AbortWithStatusJSON(400, gin.H{"error": e.GetMsg(e.AuthFail)})return err}equal, err := checkPassword(c, password, checkPassCompare)if equal == false {c.AbortWithStatusJSON(400, gin.H{"error": e.GetMsg(e.AuthFail)})return err}userQuery := &User{Username: userName,Password: checkPassCompare,}userRet := &User{}if err := db.Model(&User{}).Where(userQuery).Find(userRet).Error; err != nil {return err}logging.Info(userRet.Username)gob.Register(&User{})session, _ := store.Get(c.Request, "GOSESSID")session.Values["user-data"] = userReterr = session.Save(c.Request, c.Writer)if err != nil {//c.AbortWithStatusJSON(e.ERROR, gin.H{"error": e.GetMsg(e.AuthFail)})http.Error(c.Writer, err.Error(), http.StatusInternalServerError)return err}return nil
}
以上代码设置session,sessionId的key为GOSESSID,sessionId保存在cookie中(这句话不一定正确,只是我自己去实现后得到的结果,原本我是想copy下chatGpt的代码,结果chatGpt一直胡说八道,让我绕了很久的弯路…)。
清除session
清除session就是获取session的值,设置为nil即可,但是要注意,cookie里会记录sessionId,也需要清除:
// ClearSessions 清除session
func ClearSessions(c *gin.Context, store *sessions.CookieStore, sessionName string, cookieName string) {// 获取一个新的 session 存储器// 获取一个 sessionsession, err := store.Get(c.Request, sessionName)if err != nil {http.Error(c.Writer, err.Error(), http.StatusInternalServerError)return}session.Values[sessionName] = nil// 清除所有的 session 数据session.Options.MaxAge = -1// 保存 session 更改err = session.Save(c.Request, c.Writer)if err != nil {http.Error(c.Writer, err.Error(), http.StatusInternalServerError)return}ClearCookie(c, cookieName)// 返回成功信息logging.Info("All sessions cleared")
}// ClearCookie 清除cookie
func ClearCookie(c *gin.Context, cookieName string) {c.SetCookie(cookieName, "", -1, "/", "", false, true)logging.Info("Cookie cleared")
}
以上代码能实现一个非常基础简单的session使用。
gorilla/sessions使用redis
chatGpt多次询问,依然推荐使用github.com/gorilla/sessions/redisstore
包,然而这个包早就不维护了,使用了新版gorilla/sessions包,无法下载,会报:go: module github.com/gorilla/sessions@upgrade found (v1.2.1), but does not contain package github.com/gorilla/sessions/redisstore
,实际上,chatGpt只有21年9月份以前的数据,这是过时的。要么就是建议使用sessions.NewRedisStore
,实际上也已经没有NewRedisStore
方法了,因此先去阅读最新的gorilla/sessions包文档。
gorilla/sessions的readme中提及了两个redis相关的库:boj/redistore和…(抱歉,写一半不想写了,因为我发现这两个库上次更新时间都很久远,而且蛮多issue都没有关闭,因此不想去踩坑了,反正gin-contrib/sessions已经能用且满足需求了,就这样吧)
go(gin框架)session底层使用redis实现(gorilla/sessions和gin-contrib/sessions)相关推荐
- G0第25章:Gin框架进阶项目实战
1 Gin框架源码解析 通过阅读gin框架的源码来探究gin框架路由与中间件的秘密. 1.1 Gin框架路由详解 gin框架使用的是定制版本的httprouter,其路由的原理是大量使用公共前缀的树结 ...
- Gin框架组合(Zap、lumberjack、ini)使用手册
Gin Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,已经发布了1.0版本.具有快速灵活,容错方便等特点.其实对于golang而言,web框架的依赖要远比Python, ...
- golang gin框架gorilla的websocket小案例
golang gin框架中gorilla的websocket案例 在gin框架下 导入包 "github.com/gorilla/websocket" r.GET("/t ...
- Gin框架使用Zap接收日志
前言 日志对于项目重要性不言而喻,如果用过Gin框架大家都知道,Gin框架中自带日志logger:可以文件和控制台输出,但性能和功能远不如Zap. 一.Gin使用默认日志中间件 下面简单写个例子 fu ...
- [golang gin框架] 24.Gin 商城项目-redis讲解以及操作
一.reids相关文章 Redis五种数据类型及其应用场景 REDIS中的缓存穿透,缓存击穿,缓存雪崩原因以及解决方案 redis实现用户签到,统计活跃用户,用户在线状态,用户留存率 [golang ...
- 使用Gin框架集成JWT,源码、详解、面试问题
使用Gin框架集成JWT,源码.详解.面试问题 一.什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519). ...
- 【Gin框架】框架入门
阅读目录 一.Gin 介绍 二.Gin 环境搭建 三.golang 程序的热加载 四.Gin 框架中的路由 4.1.路由概述 4.2.简单的路由配置 4.3.c.String().c.JSON().c ...
- Gin框架从入门到上手学习指南
推荐一个Golang的学习站:Go中文学习文档 (halfiisland.com) Gin 官方文档:Gin Web Framework (gin-gonic.com) 仓库地址:gin-gonic/ ...
- Gin框架学习(三)
Gin框架基础 学习思维导图 提高篇 自定义中间件 Logger日志 JWT的认证中间件(鉴权) CORS跨域 登录中间件 后记 学习思维导图 提高篇 自定义中间件 Logger日志 package ...
最新文章
- HDU1269(强连通分量)
- Expression Tree 上手指南 (二)
- 招聘:PingCAP大范围招募,有兴趣的小伙伴速点!
- python 调用C++,传递int,char,char*,数组和多维数组
- 文档屏幕水印_您的文档何时需要屏幕截图?
- absolute如果找不到定位父元素那么会相对于谁进行定位_selenium+python面试题目总结,完整度80%,看看你会多少?...
- 苹果证实将弃用Windows版QuickTime
- 刚刚创业的你 这几点让你的公司不断前进
- ORA-01427: 单行子查询返回多个行 出现原因及对应防止措施
- day3-3.4字符编码与转码
- Daily Scrum 11/06
- FLASH寿命测试!
- python中ospathjoin_python-在Windows上与os.path.join混合斜杠
- 位(bit)、字节(Byte)、MB(兆位)换算关系
- 飞象星球落地重庆云阳86所学校,县乡4万学生迎来素质课堂
- 用伪分布式处理爬取下来的数据并用flume监听hive分析,sqoop传入MySQL并可视化
- 成人脑力训练 3.951
- python对律师的作用_法律行业python教程——利用python批量制作律师函
- 女程序员,靠脸还是靠技术?
- 数字电路实验(二)——三态门与多路复用器
热门文章
- 入门oracleDBA面试题
- 十六进制数后跟L/U/UL解析
- 企业微信如何退出之前的公司
- 国际上进行盲源分离研究的主要学者及其研究方向
- File.exists()Directory.exists()
- chrome无法添加.crx文件(扩展程序)
- 大学计算机实验图灵机模型与计算机硬件,北理大学计算机实验基础 实验一_图灵机模型与计算机硬件系统虚拟拆装-实验报告...
- eclipse安装hadoop插件教程
- 【NOIP模拟赛】小猫爬山
- python键盘键值表_Python怎么记录键盘鼠标敲击次数|Python统计鼠标点击次数 - PS下...