Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Golang Gin 实战(十三)| 中间件详解看这一篇就够了

Golang Gin 实战(十三)| 中间件详解看这一篇就够了

作者头像
飞雪无情
发布于 2020-06-30 02:28:01
发布于 2020-06-30 02:28:01
4.9K03
代码可运行
举报
运行总次数:3
代码可运行

在Gin的整个实现中,中间件可谓是Gin的精髓。一个个中间件组成一条中间件链,对HTTP Request请求进行拦截处理,实现了代码的解耦和分离,并且中间件之间相互不用感知到,每个中间件只需要处理自己需要处理的事情即可。今天我们就通过这篇文章,详细的介绍Gin中间的使用和原理。

通过这篇文章你可以学到:

  1. Gin中间件入门
  2. 如何使用Gin的默认中间件
  3. 中间件实现HTTP Basic Authorization
  4. 基于分组路由的中间件控制
  5. 自定义一个统计耗时的中间件
  6. 中间件的设计模式-责任链
  7. 自己实现一个责任链模式
  8. 中间件Next方法的实现原理
  9. Gin中间件源码分析
  10. Gin中间件面试要点

Gin默认中间件

在Gin中,我们可以通过Gin提供的默认函数,来构建一个自带默认中间件的*Engine

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
r := gin.Default()

Default函数会默认绑定两个已经准备好的中间件,它们就是Logger 和 Recovery,帮助我们打印日志输出和painc处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func Default() *Engine {
	debugPrintWARNINGDefault()
	engine := New()
	engine.Use(Logger(), Recovery())
	return engine
}

从中我们可以看到,Gin的中间件是通过Use方法设置的,它接收一个可变参数,所以我们同时可以设置多个中间件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes

到了这里其实我们应该更加明白了,一个Gin的中间件,其实就是Gin定义的一个HandlerFunc,而它在我们Gin中经常使用,比如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
r.GET("/", func(c *gin.Context) {
		fmt.Println("首页")
		c.JSON(200, "")
	})

后面的func(c *gin.Context)这部分其实就是一个HandlerFunc

中间件实现HTTP Basic Authorization

HTTP Basic Authorization 是HTTP常用的认证方案,它通过Authorization 请求消息头含有服务器用于验证用户代理身份的凭证,格式为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Authorization: Basic <credentials>

如果认证不成功,服务器返回401 Unauthorized 状态码以及WWW-Authenticate 消息头,让客户端输入用户名和密码进一步认证。

在Gin中,为我们提供了gin.BasicAuth帮我们生成基本认证的中间件,方便我们的开发。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	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都进行认证的,一般只有一些需要认证访问的数据才需要认证,比如网站的后台,那么这时候我们就可以用分组路由来处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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,就可以自定义一个自己的中间件。现在我们以统计每次请求的执行时间为例,来演示如何自定义一个中间件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 %v\n", url, costTime)
	}
}

以上我们就实现了一个Gin中间件,比较简单,而且有注释加以说明,这里要注意的是c.Next方法,这个是执行后续中间件请求处理的意思(含没有执行的中间件和我们定义的GET方法处理),这样我们才能获取执行的耗时。也就是在c.Next方法前后分别记录时间,就可以得出耗时。

有了自定义的中间件,我们就可以这么使用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main() {
	r := gin.New()

	r.Use(costTime())

	r.GET("/", func(c *gin.Context) {
		c.JSON(200, "首页")
	})

	r.Run(":8080")
}

现在启动程序,在浏览器里打开就可以看到如下日志信息了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
the request URL / cost 26.533µs

通过自定义中间件,我们可以很方便的拦截请求,来做一些我们需要做的事情,比如日志记录、授权校验、各种过滤等等。

责任链模式

在讲Gin的中间件的原理之前,我们先了解下设计模式中的责任链模式。顾名思义,责任链模式就是为请求创建一个对象链,对象链上的每个对象都可以依次对请求进行处理,并把处理过的请求传递给下一个对象。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020年6月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
你会高效写http服务器吗?Gin实战演练
胖sir开始捣鼓http服务器,在寻求一种高效的解决方式且高性能的解决方式...
阿兵云原生
2023/02/16
2.2K0
Gin框架详解
gin是一个开源的,用golang开发的web框架,https://github.com/gin-gonic/gin 地址如下。它有如下特性:
榴莲其实还可以
2019/07/19
7.4K0
Gin框架核心源码走读
| 导语 最近考虑给SCF简单封一层web库,提供cgi的http协议处理、上下文、拦截器、html渲染等能力。很自然就想到了Gin框架,基于golang且框架比较轻量,这里简单把核心源码做个走读笔记
王昂
2020/01/25
3.1K0
Gin框架核心源码走读
Gin框架系列03:换个姿势理解中间件
中间件,英译middleware,顾名思义,放在中间的物件,那么放在谁中间呢?本来,客户端可以直接请求到服务端接口。
平也
2020/04/10
1.6K1
Gin框架系列03:换个姿势理解中间件
go :gin BasicAuth中间件
本文实验 BasicAuth 中间件用法代码package mainimport ( "net/http" "github.com/gin-gonic/gin")// simulate some private datavar secrets = gin.H{ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"}, "austin": gin.H{"email": "austin@example.com", "phone
IT工作者
2022/07/22
4500
Gin-Web-Framework官方指南中文(下篇)
ShouldBind,ShouldBindJSON,ShouldBindXML,ShouldBindQuery,ShouldBindYAML
小诚信驿站
2019/10/31
2.4K0
Gin-Web-Framework官方指南中文(下篇)
gin源码阅读
c.Next()方法,这个方法的核心,主要是方便接入中间件(Middleware),使得代码模块化操作。
Michel_Rolle
2023/07/30
3K0
gin源码阅读
gin框架上手实践
Gin框架是一个用Go语言编写的高性能Web框架,以其速度和简洁性著称。它由一个轻量级的HTTP路由器和一个中间件架构组成,能够处理大型流量并简化开发者的工作。Gin的主要特点包括内置的路由组、简洁的API设计、强大的错误处理机制、支持多种格式的请求绑定和验证,以及内置的日志记录功能。由于其性能优越和易于使用,Gin广泛应用于构建RESTful API和Web服务。其设计理念是尽可能减少繁琐的配置和代码,让开发者专注于业务逻辑,实现快速开发和部署。
FunTester
2024/07/30
1690
gin框架上手实践
Gin简单明了的教程---下
Gin 框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。这个钩子函 数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、 记录日志、耗时统计等。
大忽悠爱学习
2022/08/23
1.4K0
Gin简单明了的教程---下
02 . Go框架之Gin框架从入门到熟悉(数据解析和绑定,渲染,重定向,同步异步,中间件)
json,结构体,xml, yaml类似于java的properties,protobuf
iginkgo18
2020/11/04
1.6K0
02 . Go框架之Gin框架从入门到熟悉(数据解析和绑定,渲染,重定向,同步异步,中间件)
Golang Gin 实战(七)| 分组路由源代码分析
以上等等,这些路由最前面的部分/admin/是相同的,如果我们一个个写也没问题,但是不免会觉得琐碎、重复,无用劳动,那么有没有一种更好的办法来解决呢?Gin为我们提供的解决方案就是分组路由
飞雪无情
2020/02/10
1.3K0
Web 中间件怎么玩?
Web 框架中的中间件主要指的是在 web 请求到具体路由之前或者之后,会经过一个或者多个组件进行处理一些必要的公共逻辑(业务相关或者与业务无关的),而处理这些事项的部分,就称为 web 中间件
阿兵云原生
2023/10/05
4010
Web 中间件怎么玩?
gin框架之session
session 从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道你是和谁说话呢?session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。这个时候我们可以采用session共享的方式存取session,例如我们把session放在redis、mysql、mongodb,当然这是后话,我们暂且不讨论。那么,在gin中是如何使用session的呢?
大话swift
2020/03/16
8.6K0
Gin源码解析和例子——中间件(middleware)
        在《Gin源码解析和例子——路由》一文中,我们已经初识中间件。本文将继续探讨这个技术。(转载请指明出于breaksoftware的csdn博客)
方亮
2019/01/16
1K0
Go语言学习 - RPC篇:gin框架的基础能力剖析
gin是非常流行的一款HTTP框架。相较于原生的HTTP server,gin有很多改进点,主要在于3点:
junedayday
2022/12/02
1.5K0
Go语言学习 - RPC篇:gin框架的基础能力剖析
Gin 框架怎么使用中间件?
阅读上面这段代码,我们可以发现,Gin 框架使用 Use 方法,使用中间件,包含默认中间件和自定义中间件。
frank.
2024/12/09
1870
Gin 框架怎么使用中间件?
01 . Go框架之Gin框架从入门到熟悉(路由和上传文件)
路由方法有GET, POST, PUT, PATCH, DELETE 和 OPTIONS,还有Any,可匹配以上任意类型的请求
iginkgo18
2020/10/30
1.6K0
Golang框架Gin入门实战--(8)Gin中间件详解 路由中间件 全局中间件 路由分组中间件
根据上篇文章进行修改 只把修改过的文件进行展示 没修改过的跟之上一篇一样 目录结构
互联网-小阿宇
2022/11/21
1K0
Golang框架Gin入门实战--(8)Gin中间件详解 路由中间件 全局中间件 路由分组中间件
Go语言(十三)Gin Web框架
Gin Web框架 简介 基于httprouter开发的web框架:https://github.com/gin-gonic/gin 提供Martini风格的API,但比Martini要快40倍 非常轻量级,使用简洁 Gin框架的安装与使用 安装: go get -u github.com/gin-gonic/gin 基本使用 import "github.com/gin-gonic/gin" func main() { r := gin.Default() r.GET("/ping", fu
alexhuiwang
2020/09/24
9140
Go语言(十三)Gin Web框架
Go框架解析-Gin
今天是我golang框架阅读系列第三篇文章,今天我们主要看看gin的框架执行流程。关于golang框架生命周期源码阅读下面是我的计划:
用户1093396
2020/10/29
1.3K0
Go框架解析-Gin
相关推荐
你会高效写http服务器吗?Gin实战演练
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验