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框架中中间件的编写与使用
概念 一个完整的系统可能包括鉴权认证.权限管理.安全检查.日志记录等多维度的系统支持. 中间件位与服务器和实际业务处理程序之间,其含义就相当于在请求和具体的业务处理逻辑之间增加某些操作,这种以额外增加 ...
随机推荐
- Chrome导出导入书签
Chrome导出标签 Chrome导入书签
- SpringBoot整合Apache Shiro
Subject 用户主体 (把操作交给SecurityManager)SecurityManager 安全管理器 (关联Realm)Realm Shiro连接数据的桥梁 引入maven依赖 < ...
- JAVA使用经纬度通过腾讯地图API获取详细地址
官方文档:https://lbs.qq.com/service/webService/webServiceGuide/webServiceGcoder package com.weixin.map; ...
- 【LeetCode】5685. 交替合并字符串 Merge Strings Alternately (Python)
作者: 负雪明烛 id: fuxuemingzhu 公众号:每日算法题 本文关键词:LeetCode,力扣,算法,算法题,交替合并字符串,Merge Strings Alternately,刷题群 目 ...
- 【LeetCode】841. Keys and Rooms 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...
- lightoj 1102 - Problem Makes Problem
1102 - Problem Makes Problem As I am fond of making easier problems, I discovered a problem. Actuall ...
- CRB and His Birthday(hdu 5410)
CRB and His Birthday Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- 【项目管理】《IT项目管理》Kathy Schwalbe 第2章 IT项目管理和IT背景
1.对项目管理采取系统的观点有何意义?如何在项目管理中采用系统的观点? 意义:有效处理复杂的环境 采用系统方法,系统分析,系统管理.2.解释组织的四个框架.他们是如何帮助项目经理理解项目的组织环境的? ...
- BBN+
目录 motivation settings results motivation 观测用BBN的模式训练出来的模型, 配上不同的\(\alpha\), 结果会如何. settings Attribu ...
- pycharm遇到的小问题
1. Pycharm编写的代码出现满屏的波浪线,如何去除>>>点击右下角的小人图标将箭头移到中间syntax处即可. 2. 运行时报错: UserWarning: No parser ...