gin框架中的会话控制
Cookie介绍
- Http协议是无状态的,服务器不能记录浏览器的访问状态,也就是说服务器不能判断请求的客户端是否已经登录
- Cookie就是解决http协议无状态的方案之一
- Cookie实际上就是服务器保存在浏览器上的一小段文本信息,浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该信息处理请求
- Cookie由服务器创建,并发送给浏览器,最终由浏览器进行保存
cookie的用途:
测试服务端发送cookie给客户端,客户端请求时携带cookie
Cookie的使用
测试服务端发送cookie给客户端,客户端请求时携带cookie
func someCookie(context *gin.Context) {
cookie, err := context.Cookie("key_cookie")
if err != nil {
// 给客户端设置cookie
context.SetCookie(
"key_cookie",
"value_cookie",
60, // maxAge int, 单位为秒
"/", // path,cookie所在目录
"127.0.0.1", // domain string,域名
false, // secure 是否智能通过https访问
false, // httpOnly bool 是否允许别人通过js获取自己的cookie
)
}
fmt.Println("cookie的值是:", cookie)
}
Cookie的练习
模拟实现权限验证中间件
- 有2个路由,login和home
- login用于设置cookie
- home是访问查看信息的请求
- 在请求home之前,先跑中间件代码,检验是否存在cookie
访问home,会显示错误,因为权限校验未通过

然后访问登录的请求,登录并设置cookie

再次访问home,访问成功

- 认证中间件代码
func AuthMiddleware() gin.HandlerFunc {
return func(context *gin.Context) {
// 获取客户端cookie并校验
if cookie, err := context.Cookie("username"); err == nil {
if cookie == "mayanan" {
context.Next()
return
}
}
// 返回错误
context.JSON(http.StatusUnauthorized, gin.H{"data": "认证失败"})
// 若认证失败,不用调用后续的函数处理
context.Abort()
return
}
}
- 处理请求函数
func someLogin(context *gin.Context) {
context.SetCookie(
"username",
"mayanan",
60, // maxAge int, 单位为秒
"/", // path,cookie所在目录
"127.0.0.1", // domain string,域名
false, // secure 是否智能通过https访问
false, // httpOnly bool 是否允许别人通过js获取自己的cookie
)
context.JSON(200, "登录成功")
}
func someHome(context *gin.Context) {
context.JSON(200, gin.H{"data": "home"})
}
- 路由设置
router.GET("/some-login", someLogin)
router.GET("/some-home", middleware.AuthMiddleware(), someHome)
Cookie的缺点
- 不安全,明文
- 增加带宽消耗
- 可以被禁用
- cookie有上限
Sessions
gorilla/sessions为自定义session后端提供cookie和文件系统session以及基础结构。
github链接
主要功能是:
简单的API:将其用作设置签名(以及可选的加密)cookie的简便方法。
内置的后端可将session存储在cookie或文件系统中。
Flash消息:一直持续读取的session值。
切换session持久性(又称“记住我”)和设置其他属性的便捷方法。
旋转身份验证和加密密钥的机制。
每个请求有多个session,即使使用不同的后端也是如此。
自定义session后端的接口和基础结构:可以使用通用API检索并批量保存来自不同商店的session。
基于session实现上面的练习
- session-login session-home
func sessionLogin(context *gin.Context) {
// 初始化一个cookie存储对象
// mayanan.cn是一个自己的秘钥
var store = sessions.NewCookieStore([]byte("mayanan.cn"))
// 获取一个session对象,session-name是session的名字
session, err := store.Get(context.Request, "session-name")
if err != nil {
fmt.Println(err)
return
}
// 在session中存储值
session.Values["foo"] = "bar"
session.Values[42] = 43
// 保存更改 session默认过期时间:一个月
session.Save(context.Request, context.Writer)
context.JSON(http.StatusOK, "登录成功")
}
func sessionHome(context *gin.Context) {
context.JSON(200, gin.H{"data": "sessionHome"})
}
- 中间件获取session,如果解析失败,拦截请求
func AuthMiddlewareSession() gin.HandlerFunc {
var store = sessions.NewCookieStore([]byte("mayanan.cn"))
return func(context *gin.Context) {
session, err := store.Get(context.Request, "session-name")
if err != nil {
context.JSON(http.StatusUnauthorized, gin.H{"err": err})
context.Abort() // 结束后续的请求处理
return
}
fooInfo := session.Values["foo"]
age := session.Values[42]
if fooInfo == "bar" && age == 43 {
context.Next()
return
}
context.JSON(http.StatusUnauthorized, gin.H{
"err": "身份认证失败",
})
context.Abort()
return
}
}
- 路由配置
router.GET("/session-login", sessionLogin)
router.GET("/session-home", middleware.AuthMiddlewareSession(), sessionHome)
- 删除session值
将session的最大存储时间设置为小于零的数即为删除
session.Options.MaxAge = -1
session.Save(r, w)
案例:
func sessionDelete(context *gin.Context) {
story := sessions.NewCookieStore([]byte("mayanan.cn"))
session, err := story.Get(context.Request, "session-name")
if err != nil {
context.JSON(http.StatusUnauthorized, err.Error())
context.Abort()
return
}
session.Options.MaxAge = -1
session.Save(context.Request, context.Writer)
context.String(200, "session删除成功")
}
gin框架中的会话控制的更多相关文章
- 在gin框架中使用JWT
在gin框架中使用JWT JWT全称JSON Web Token是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场景下. 什么 ...
- golang gin框架中实现一个简单的不是特别精确的秒级限流器
起因 看了两篇关于golang中限流器的帖子: Gin 开发实践:如何实现限流中间件 常用限流策略--漏桶与令牌桶介绍 我照着用,居然没效果-- 时间有限没有深究.这实在是一个很简单的功能,我的需求是 ...
- gin框架中请求路由组的使用
1. gin框架中可以使用路由组来实现对路由的分类 package main import "github.com/gin-gonic/gin" func main() { rou ...
- gin框架中的路由
基本路由 gin框架中采用的路由库是基于httrouter做的 地址为:https://github.com/julienschmidt/httprouter httprouter路由库 点击查看代码 ...
- PHP中的会话控制
了解HTTP(超文本传输协议)可以知道,它采用请求与响应的模式,最大的特点就是无连接无状态. 无连接:每次连接仅处理一个客户端的请求,得到服务器响应后,连接就结束了 无状态:每个请求都是独立的,服务器 ...
- 理解PHP中的会话控制
会话控制是一种跟踪用户的通信方式,使用会话控制主要基于以下几点:由于http协议的无状态性,使得不能通过协议来建立两次请求之间的关联:对于通常的页面之间的数据传递方式get和post而言,主要处理参数 ...
- 【解决了一个小问题】gin框架中出现如下错误:"[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 500"
POST到数据到一条gin框架的接口后,客户端收到400错误,并且返回了业务中返回的"decode json fail". 关键代码是: func report(c *gin.Co ...
- golang gin框架中实现大文件的流式上传
一般来说,通过c.Request.FormFile()获取文件的时候,所有内容都全部读到了内存.如果是个巨大的文件,则可能内存会爆掉:且,有的时候我们需要一边上传一边处理. 以下的代码实现了大文件流式 ...
- gin框架中中间件的编写与使用
概念 一个完整的系统可能包括鉴权认证.权限管理.安全检查.日志记录等多维度的系统支持. 中间件位与服务器和实际业务处理程序之间,其含义就相当于在请求和具体的业务处理逻辑之间增加某些操作,这种以额外增加 ...
随机推荐
- 10-2 bonding
创建bonding设备的配置文件 centos8 /etc/sysconfig/network-scripts/ifcfg-bond0 NAME=bond0 TYPE=bond DEVICE=bond ...
- 【LeetCode】1464. 数组中两元素的最大乘积 Maximum Product of Two Elements in an Array (Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 找最大次大 日期 题目地址:https://le ...
- 【LeetCode】845. Longest Mountain in Array 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双数组 参考资料 日期 题目地址:https://l ...
- 【LeetCode】160. Intersection of Two Linked Lists 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 栈 日期 题目地址:https://leet ...
- MacOS使用Docker创建MySQL主主数据库
主从同步配置可以参考上一篇MacOS使用Docker创建MySQL主从数据库 一.创建MySQL数据库容器配置文件对应目录 我们在当前用户下创建一组目录,用来存放MySQL容器配置文件,(Linux下 ...
- 【计算机组成】 Quartus II 关于总线data[][]转换多个总线data[]时不成功的问题
xjtuse 直接使用报错: 加中间层不报错:
- Proximal Algorithms 5 Parallel and Distributed Algorithms
目录 问题的结构 consensus 更为一般的情况 Exchange 问题 Global exchange 更为一般的情况 Allocation Proximal Algorithms 这一节,介绍 ...
- Essentially No Barriers in Neural Network Energy Landscape
目录 梗概 主要内容 path的定义 path的逼近 Mechanical Model Nudged Elastic Band 局部最优 Draxler F, Veschgini K, Salmhof ...
- CS5266替代AG9311设计TYPEC转HDMI带PD3.0音视频拓展坞方案
CS5266替代AG9311设计TYPEC转HDMI带PD3.0音视频拓展坞方案台湾安格AG9311是一款TYPEC转HDMI带PD3.0的音视频转换芯片,它主要用在USB TYPEC拓展坞或者USB ...
- 使用 IE 或Chrome等浏览器,通过网络抓包的形式,查看发送请求时的网络
要求: 使用 IE 或Chrome等浏览器,通过网络抓包的形式,查看发送请求时的网络 实现步骤: 1.打开 IE 浏览器,选择"开发者工具",切换到"网络"标签 ...