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的练习

  • 模拟实现权限验证中间件

    1. 有2个路由,login和home
    2. login用于设置cookie
    3. home是访问查看信息的请求
    4. 在请求home之前,先跑中间件代码,检验是否存在cookie
  • 访问home,会显示错误,因为权限校验未通过

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

  • 再次访问home,访问成功

  1. 认证中间件代码
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
}
}
  1. 处理请求函数
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"})
}
  1. 路由设置
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删除成功")
}
  • session默认存储到了签名的cookie中了
  • 如果想存储到mysql中:github链接
  • 存储到redis中:github链接

gin框架中的会话控制的更多相关文章

  1. 在gin框架中使用JWT

    在gin框架中使用JWT JWT全称JSON Web Token是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场景下. 什么 ...

  2. golang gin框架中实现一个简单的不是特别精确的秒级限流器

    起因 看了两篇关于golang中限流器的帖子: Gin 开发实践:如何实现限流中间件 常用限流策略--漏桶与令牌桶介绍 我照着用,居然没效果-- 时间有限没有深究.这实在是一个很简单的功能,我的需求是 ...

  3. gin框架中请求路由组的使用

    1. gin框架中可以使用路由组来实现对路由的分类 package main import "github.com/gin-gonic/gin" func main() { rou ...

  4. gin框架中的路由

    基本路由 gin框架中采用的路由库是基于httrouter做的 地址为:https://github.com/julienschmidt/httprouter httprouter路由库 点击查看代码 ...

  5. PHP中的会话控制

    了解HTTP(超文本传输协议)可以知道,它采用请求与响应的模式,最大的特点就是无连接无状态. 无连接:每次连接仅处理一个客户端的请求,得到服务器响应后,连接就结束了 无状态:每个请求都是独立的,服务器 ...

  6. 理解PHP中的会话控制

    会话控制是一种跟踪用户的通信方式,使用会话控制主要基于以下几点:由于http协议的无状态性,使得不能通过协议来建立两次请求之间的关联:对于通常的页面之间的数据传递方式get和post而言,主要处理参数 ...

  7. 【解决了一个小问题】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 ...

  8. golang gin框架中实现大文件的流式上传

    一般来说,通过c.Request.FormFile()获取文件的时候,所有内容都全部读到了内存.如果是个巨大的文件,则可能内存会爆掉:且,有的时候我们需要一边上传一边处理. 以下的代码实现了大文件流式 ...

  9. gin框架中中间件的编写与使用

    概念 一个完整的系统可能包括鉴权认证.权限管理.安全检查.日志记录等多维度的系统支持. 中间件位与服务器和实际业务处理程序之间,其含义就相当于在请求和具体的业务处理逻辑之间增加某些操作,这种以额外增加 ...

随机推荐

  1. 分布式NoSQL数据库MongoDB初体验-v5.0.5

    概述 定义 MongoDB官网 https://www.mongodb.com/ 社区版最新版本5.0,其中5.2版本很快也要面世了 MongoDB GitHub源码 https://github.c ...

  2. ubuntu ffmpeg 转码错误

    [aac @ 0xde2400] The encoder 'aac' is experimental but experimental codecs are not enabled, add '-st ...

  3. nim_duilib(16)之xml学习实战(GTAV加载窗口实现)

    本文的目标 使用配置xml实现下面的结果 布局 整体采用水平布局,左边显示文字区域设置为垂直布局. lets go stage 1 创建一个空白窗体,并设置为半透明:同时,使得整个窗口可以移动,则 将 ...

  4. 【LeetCode】5083. Occurrences After Bigram 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字符串分割遍历 日期 题目地址:https://le ...

  5. 【LeetCode】563. Binary Tree Tilt 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Java解法 Python解法 日期 题目地址:ht ...

  6. 设置div背景透明的两种方法

    实现div背景透明的两种方法 1.使用opacity属性 background-color:#000; opacity: 0.5; 这样做可以设置div内部所以区域的透明度,但是也会影响里面的文字,效 ...

  7. RabbitMQ,RocketMQ,Kafka 事务性,消息丢失和消息重复发送的处理策略

    消息队列常见问题处理 分布式事务 什么是分布式事务 常见的分布式事务解决方案 基于 MQ 实现的分布式事务 本地消息表-最终一致性 MQ事务-最终一致性 RocketMQ中如何处理事务 Kafka中如 ...

  8. 简单学生管理系统HTML前端页面

    效果图: 实现代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...

  9. ElasticSearch+Kibana安装部署

    在安装ElasticSearch时遇到了很多坑,所以在这里做个笔记记录一下. 首先我考虑的是使用docker进行部署,结果发现虚拟机直接内存溢出,我也是无解了,也就是说使用docker部署还得注意容器 ...

  10. golang mongodb 驱动二次封装

    mongodb 官方的go驱动包 go.mongodb.org/mongo-driver 使用起来比较繁琐,最近对其进行了二次封装 github地址:https://github.com/w3liu/ ...