代理后台中间件_Golang Gin 实战(十三)| 中间件详解看这一篇就够了
6000字大章带你死磕Golang Gin中间件
在Gin的整个实现中,中间件可谓是Gin的精髓。一个个中间件组成一条中间件链,对HTTP Request请求进行拦截处理,实现了代码的解耦和分离,并且中间件之间相互不用感知到,每个中间件只需要处理自己需要处理的事情即可。今天我们就通过这篇文章,详细的介绍Gin中间的使用和原理。
通过这篇文章你可以学到:
- Gin中间件入门
- 如何使用Gin的默认中间件
- 中间件实现HTTP Basic Authorization
- 基于分组路由的中间件控制
- 自定义一个统计耗时的中间件
- 中间件的设计模式-责任链
- 自己实现一个责任链模式
- 中间件Next方法的实现原理
- Gin中间件源码分析
- Gin中间件面试要点
Gin默认中间件
在Gin中,我们可以通过Gin提供的默认函数,来构建一个自带默认中间件的*Engine
。
r := gin.Default()
Default
函数会默认绑定两个已经准备好的中间件,它们就是Logger 和 Recovery,帮助我们打印日志输出和painc
处理。
func Default() *Engine {debugPrintWARNINGDefault()engine := New()engine.Use(Logger(), Recovery())return engine
}
从中我们可以看到,Gin的中间件是通过Use
方法设置的,它接收一个可变参数,所以我们同时可以设置多个中间件。
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes
到了这里其实我们应该更加明白了,一个Gin的中间件,其实就是Gin定义的一个HandlerFunc
,而它在我们Gin中经常使用,比如:
r.GET("/", func(c *gin.Context) {fmt.Println("首页")c.JSON(200, "")})
后面的func(c *gin.Context)
这部分其实就是一个HandlerFunc
。
中间件实现HTTP Basic Authorization
HTTP Basic Authorization 是HTTP常用的认证方案,它通过Authorization 请求消息头含有服务器用于验证用户代理身份的凭证,格式为:
Authorization: Basic <credentials>
如果认证不成功,服务器返回401 Unauthorized 状态码以及WWW-Authenticate 消息头,让客户端输入用户名和密码进一步认证。
在Gin中,为我们提供了gin.BasicAuth
帮我们生成基本认证的中间件,方便我们的开发。
r := gin.Default()r.Use(gin.BasicAuth(gin.Accounts{"admin": "123456",}))r.GET("/", func(c *gin.Context) {c.JSON(200, "首页")})r.Run(":8080")
我们添加一个用户名为admin
,密码是123456
的账户,用于HTTP 基本认证。现在我们运行启动,访问http://localhost:8080/
,这时候只有我们输入正确的用户名和密码,才能看到首页
,否则是看不到的,这样我们就达到了授权的目的,就是这么简单。
针对特定URL的Basic Authorization
其实在实际的项目开发中,我们基本上不太可能对所有的URL都进行认证的,一般只有一些需要认证访问的数据才需要认证,比如网站的后台,那么这时候我们就可以用分组路由来处理。
func main() {r := gin.Default()r.GET("/", func(c *gin.Context) {c.JSON(200, "首页")})adminGroup := r.Group("/admin")adminGroup.Use(gin.BasicAuth(gin.Accounts{"admin": "123456",}))adminGroup.GET("/index", func(c *gin.Context) {c.JSON(200, "后台首页")})r.Run(":8080")
}
现在我们运行访问/
首页是可以正常显示的,但是我们访问/admin/index
会提示输入密码,其实所有/admin/*
下的URL都会让输入密码才能访问,这就是我们分组路由的好处,我们通过把中间件加到/admin
这个分组路由上,就可以达到我们的目的。
通过分组路由的控制,我们可以比较灵活的设置HTTP认证,粒度可以自己随意控制。
自定义中间件
我们已经知道,Gin的中间件其实就是一个HandlerFunc
,那么只要我们自己实现一个HandlerFunc
,就可以自定义一个自己的中间件。现在我们以统计每次请求的执行时间为例,来演示如何自定义一个中间件。
func costTime() gin.HandlerFunc {return func(c *gin.Context) {//请求前获取当前时间nowTime := time.Now()//请求处理c.Next()//处理后获取消耗时间costTime := time.Since(nowTime)url := c.Request.URL.String()fmt.Printf("the request URL %s cost %vn", url, costTime)}
}
以上我们就实现了一个Gin中间件,比较简单,而且有注释加以说明,这里要注意的是c.Next
方法,这个是执行后续中间件请求处理的意思(含没有执行的中间件和我们定义的GET方法处理),这样我们才能获取执行的耗时。也就是在c.Next
方法前后分别记录时间,就可以得出耗时。
有了自定义的中间件,我们就可以这么使用。
func main() {r := gin.New()r.Use(costTime())r.GET("/", func(c *gin.Context) {c.JSON(200, "首页")})r.Run(":8080")
}
现在启动程序,在浏览器里打开就可以看到如下日志信息了。
the request URL / cost 26.533µs
通过自定义中间件,我们可以很方便的拦截请求,来做一些我们需要做的事情,比如日志记录、授权校验、各种过滤等等。
责任链模式
在讲Gin的中间件的原理之前,我们先了解下设计模式中的责任链模式。顾名思义,责任链模式就是为请求创建一个对象链,对象链上的每个对象都可以依次对请求进行处理,并把处理过的请求传递给下一个对象。
看上图比较形象,从左到右横向是一个请求,在请求之上的是一个个对象(1-5),这5个对象就组成了处理责任链,依次对请求进行处理,并且处理完之后,把请求传递给下一个对象处理,生动描述详见下图:
剩余精彩核心原理部分请点击:
Golang Gin 实战(十三)| 中间件详解看这一篇就够了mp.weixin.qq.com
精彩文章推荐
Golang Gin 实战(十二)| ProtoBuf 使用和源码分析原理实现
Golang Gin 实战(十一)| HTML模板渲染
Golang Gin 实战(十)| XML渲染
Golang Gin 实战(九)| JSONP跨域和劫持
Golang Gin 实战(八)| JSON渲染输出
我有几个的Go语言交流微信群,可以扫码关注公众号flysnow_org
或者网站 https://www.flysnow.org/,加我好友,我拉你进来。
代理后台中间件_Golang Gin 实战(十三)| 中间件详解看这一篇就够了相关推荐
- JAVA 支付宝支付系统实战项目超详解
结合支付宝官网实现的 支付宝当面支付功能,非常详细看我一篇就够了 1. 目的 2. 说明 3. 申请支付宝的账号(每个人都有做,不要用我的) 3.1. 扫码登陆 3.2. 账号的申请 3.3. 记录你 ...
- Elasticsearch实战——function_score 查询详解
Elasticsearch实战--function_score 查询详解 文章目录 Elasticsearch实战--function_score 查询详解 1. function_score简介 2 ...
- HMI智能串口屏——在STM32开发板上的实战应用及其详解
HMI智能串口屏--在STM32开发板上的实战应用及其详解 一.HMI智能串口屏使用步骤 二.附录 一.HMI智能串口屏使用步骤 安装USART HMI软件 (一般买的串口屏里面,商家送的资料里面都有 ...
- c++入门代码_Golang Gin 实战(一)| 快速安装入门
Golang Gin 实战(一)| 快速安装入门 Gin 是一个非常优秀的Golang Web Framework,它不光API友好,性能也非常高,并且设计简洁,便于入门.所以它(Gin)非常受欢迎, ...
- html获取url后面的参数_Golang Gin 实战(四)| URL查询参数的获取和原理分析
在 上一篇 Golang Gin 实战(三)| 路由参数 文章中,主要介绍了路由通配符.路由参数,让我们有了一种可以从URL路径中获取参数的方式,同时又不是重复的注册相似的路由. 这一篇,主要介绍查询 ...
- 中间件:ElasticSearch组件RestHighLevelClient用法详解
本文源码:GitHub·点这里 || GitEE·点这里 一.基础API简介 1.RestHighLevelClient RestHighLevelClient的API作为ElasticSearch备 ...
- [Golang梦工厂]一个小项目带你学会GIN框架、JWT鉴权、swagger生成接口文档,看这一篇就够了
前言 哈喽,大家好,我是asong,这是我的第八篇原创文章.听说你们还不会jwt.swagger,所以我带来一个入门级别的小项目.实现用户登陆.修改密码的操作.使用GIN(后台回复Golang梦工厂: ...
- java面试题,看我这篇就够了,前端后台应有尽有,包你通过面试
面试题精华版:https://blog.csdn.net/cencong863251/article/details/88963573 以下为详情版: HTML&CSS部分 1.HTML中定义 ...
- docker 镜像修改的配置文件自动还原_Docker 基础与实战,看这一篇就够了
作者 | 单一色调责编 | ElleDocker 基础 什么是Docker Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,names ...
最新文章
- getElementById 使用
- 判断远程文件是否存在
- Spark系列(八)Worker工作原理
- 深入理解JVM(8)——类加载的时机
- CPU乱序执行(指令重排序)
- uva 11584——Partitioning by Palindromes
- ubuntu 16.04 更改jupyter notebook工作路径
- 博文内部设置目录尝试
- JAVA实现Word转Pdf文件
- BT5中安装VMWare Tool的相关命令
- 迪恩素材教程资源图片下载站源码 dz社区论坛discuz 模板
- nosqlbooster pojie
- 好消息!这些城市个人手机、在家“刷脸”都能提取公积金,有你家吗?
- netty报错:LEAK: ByteBuf.release() was not called before it‘s garbage-collected
- matlab figure 虚线圆,flutter 画圆,虚线圆,渐变圆
- 2019年面试大概问题
- 详细前端面试题javascript篇--持续更新
- 潦草字体在线识别_连笔字在线生成器
- 【SemiDrive源码分析】【X9芯片启动流程】12 - freertos_safetyos目录Cortex-R5 DIL2.bin 之 sdm_display_init 显示初始化源码分析
- 稳定性全系列(二)——如何做线上全链路压测
热门文章
- Java:基于LinkedList实现栈和队列
- ASP.NET - JQuery的.getJSON给Dropdownlist绑定Item
- 使用DevExpress的WebChartControl控件绘制图表(柱状图、折线图、饼图)
- asp 文件上传 代码
- 陕西西咸新区暨沣渭新区泾渭新区网上截图!
- 【报告分享】2020海外留学趋势报告.pdf(附下载链接)
- 【报告分享】直播电商生态进化论-2020直播电商行业研究报告.pdf(附下载链接)...
- tmux鼠标操作配置
- C++将double类型小数以16进制格式打印出
- 蓝桥杯 算法训练 Sticks