[每周一更]-(第83期):Go新项目-Gin中间件的使用和案例(10)

在这里插入图片描述

在 Gin 中,中间件是一种用于处理 HTTP 请求和响应的功能强大的机制。中间件是一段位于请求处理链和最终处理器之间的代码,
它可以截获请求、执行预处理操作,修改请求或响应,然后将控制权传递给下一个中间件或最终的请求处理器。

中间价在业务使用中,方便注入一些业务无关的逻辑,并且方便移植到特质的接口中;

下文会聊下:日志、ip限制、API请求速率控制、跨域请求;

以下是 Gin 中间件的概念和使用方式:

概念

执行顺序: Gin 中的中间件按照它们添加的顺序执行。先添加的中间件先执行。

中断处理链: 中间件可以选择中断处理链,阻止后续的中间件和处理器执行。

修改请求和响应: 中间件可以修改请求的内容,也可以修改响应的内容。这使得中间件非常灵活,可以用于日志记录、认证、跨域处理等多种用途。

1、日志

使用方式
  1. 引入 Gin 包:
import "github.com/gin-gonic/gin"
  1. 定义中间件函数:

中间件函数是一个接受 *gin.Context 参数的函数。例如,一个简单的日志记录中间件:

func LoggerMiddleware(c *gin.Context) {// 执行处理之前的逻辑fmt.Println("Start Request")// 继续处理链c.Next()// 处理之后的逻辑fmt.Println("End Request")
}
  1. 使用中间件:

在路由组或路由上使用中间件。以下是一个简单的使用示例:

func main() {r := gin.Default()// 使用自定义中间件r.Use(LoggerMiddleware)// 路由定义r.GET("/ping", func(c *gin.Context) {c.String(200, "pong")})// 启动服务r.Run(":8080")
}

在上面的例子中,LoggerMiddleware 将在每个请求前后打印日志。

自定义中间件

你可以通过编写函数来创建自定义中间件。以下是一个例子,演示了一个处理请求头的中间件:

func CustomMiddleware() gin.HandlerFunc {return func(c *gin.Context) {// 在请求处理之前执行的逻辑c.Header("Custom-Header", "Custom Value")// 继续处理链c.Next()// 在请求处理之后执行的逻辑}
}

然后,你可以像下面这样使用自定义中间件:

goCopy code
func main() {r := gin.Default()// 使用自定义中间件r.Use(CustomMiddleware())// 路由定义r.GET("/ping", func(c *gin.Context) {c.String(200, "pong")})// 启动服务r.Run(":8080")
}

这个自定义中间件简单地在每个请求中添加了一个自定义的响应头。

注:某些单独接口使用 中间件(一般都是全局设置)

r.POST("demo-middleware",IP,Rate,demo.Action)

2、校验IP

调用开源库:GeoLite2-Country/GeoLite2-Country.mmdb,进行比对判断是否为国内IP

package middlewareimport ("net""net/http""github.com/gin-gonic/gin""github.com/oschwald/geoip2-golang"
)// IP 校验ip,非国内ip禁止访问。采用geoip2-lite数据库,免费版本,不保证准确率
func IP() gin.HandlerFunc {return func(c *gin.Context) {db, err := geoip2.Open(config.Env.GetString("app.mmdb_path"))if err != nil {panic(err)}defer db.Close()ip := net.ParseIP(c.GetHeader("X-Real-IP"))ipInfo, err := db.Country(ip)if err == nil {if ipInfo.Country.IsoCode != "CN" && ipInfo.Country.IsoCode != "" {response.CustomErrorJson(c, http.StatusBadRequest, response.NOT_PERMISSION,"禁止非中国用户访问", map[string]any{"errors": "禁止非中国用户访问"})return}}}// 处理请求c.Next() //  处理请求
}

3、API接口速度控制

接口请求速度控制,防止恶意爬虫或者恶意请求数据,导致服务资源紧张;

package middlewareimport ("net/http""github.com/gin-gonic/gin""golang.org/x/time/rate"
)var limiter *rate.Limiterfunc init() {// 令牌桶大小为60,每秒产生1个token,即每分钟最多处理60个请求limiter = rate.NewLimiter(1, 60)
}func Rate() gin.HandlerFunc {return func(ctx *gin.Context) {if !limiter.Allow() {response.CustomErrorJson(ctx, http.StatusBadRequest, response.RATE_LIMIT,"请求过于频繁,请稍后重试", map[string]any{"errors": "请求过于频繁,请稍后重试"})return}// 处理请求c.Next() //  处理请求}
}

4、跨域请求

package middlewareimport ("net/http""github.com/gin-gonic/gin"
)func Cors() gin.HandlerFunc {return func(c *gin.Context) {method := c.Request.Method               // 请求方法origin := c.Request.Header.Get("Origin") // 请求头部var headerKeys []string                  // 声明请求头keysfor k, _ := range c.Request.Header {headerKeys = append(headerKeys, k)}headerStr := strings.Join(headerKeys, ", ")if headerStr != "" {headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)} else {headerStr = "access-control-allow-origin, access-control-allow-headers"}if origin != "" {c.Writer.Header().Set("Access-Control-Allow-Origin", "*")c.Header("Access-Control-Allow-Origin", "*")                                       // 这是允许访问所有域c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") // 服务器支持的所有跨域请求的方法,为了避免浏览次请求的多次'预检'请求//  header的类型c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token,"+" Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, "+"Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, "+"Cache-Control, Content-Type, Pragma")// 允许跨域设置         可以返回其他子段c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, "+"Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域关键设置 让浏览器可以解析c.Header("Access-Control-Max-Age", "172800")          // 缓存请求信息 单位为秒c.Header("Access-Control-Allow-Credentials", "false") //  跨域请求是否需要带cookie信息 默认设置为truec.Set("content-type", "application/json")             // 设置返回格式是json}// 放行所有OPTIONS方法if method == "OPTIONS" {c.JSON(http.StatusOK, "Options Request!")}// 处理请求c.Next() //  处理请求}
}

参考地址

  • https://dev.maxmind.com/geoip/geolite2-free-geolocation-data
  • https://github.com/oschwald/geoip2-golang?tab=readme-ov-file

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/414992.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu系统 vscode 配置c/c++调试环境

文章目录 1.安装插件2.目录结构3.cmake tools配置 1.安装插件 c/c插件 cmake cmake tools插件 2.目录结构 . ├── build ├── CMakeLists.txt ├── demo │ └── main.cpp ├── image.png ├── src │ ├── add.cpp │ └── add.hpp └── vsdebug.…

关于电脑是否支持或开启TPM 2.0,看这篇文章就够了

本指南将教你如何启用TPM 2.0。如果你想运行Windows 11,这是必需的。 如何启用TPM 2.0 如果你的电脑硬件支持TPM 2.0,但未启用,则可以通过UEFI/BIOS执行此操作。以下是一般指南: 1、进入UEFI/BIOS。 2、在名为“安全”或“高级…

48-DOM节点,innerHTML,innerText,outerHTML,outerText,静态获取,单机click,cssText

1.DOM基础 Document Object Module,文档对象模型,window对象,document文档,都可以获取和操作 1)文档节点 2)属性节点(标签内的属性href,src) 3)文本节点(标签内的文字) 4)注释节点 5)元素节点(标签) 2.获取元素节点 2.1通过标签名获取getElementsByTagName() …

pdf怎么查看?6个不能错过的软件!

PDF,作为一种常用的文件格式,已经成为了我们工作、学习中的必备工具。然而,对于许多新手来说,如何查看和编辑PDF文件却是一个不小的挑战。今天,我们就来为大家详细介绍一下如何查看和编辑PDF文件,以及一些必…

中间件框架知识进阶

概述 近期从不同渠道了解到了一些中间件相关的新的知识,记录一下收获。涉及到的中间件包括RPC调用、动态配置中心、MQ、缓存、数据库、限流等,通过对比加深理解,方便实际应用时候更明确如何进行设计和技术选型。 一、RPC框架中间件系列 1、…

第一讲_HarmonyOS应用开发环境准备

HarmonyOS应用开发环境准备 1. 知识储备2. 环境搭建2.1 安装node.js2.2 配置node.js2.3 安装命令行工具2.4 安装DevEco Studio2.5 配置DevEco Studio 1. 知识储备 HarmonyOS提供了一套UI开发框架,即方舟开发框架(ArkUI框架)。方舟开发框架可…

基于SpringBoot微信小程序的宠物美容预约系统设计与实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作✌ 主要内容:SpringBoot、Vue、SSM、HLM…

可视化神器Plotly绘制金融图表

公众号:尤而小屋作者:Peter编辑:Peter 大家好,我是Peter~ 好久没有更新关于plotly的文章。 什么是Plotly? Plotly是一个基于JavaScript的绘图库,可以创建各种类型的图表,包括散点图、折线图、面积图、条形…

随笔03 笔记整理

图源:文心一言 关于我的考研与信息安全类博文整理~🥝🥝 第1版:整理考研类博文~🧩🧩 第2版:提前列出博文链接,以便小伙伴查阅~🧩🧩 第3版:整理We…

【漏洞攻击之文件上传条件竞争】

漏洞攻击之文件上传条件竞争 wzsc_文件上传漏洞现象与分析思路编写攻击脚本和重放措施中国蚁剑拿flag wzsc_文件上传 漏洞现象与分析 只有一个upload前端标签元素,并且上传任意文件都会跳转到upload.php页面,判定是一个apache容器,开始扫描…

K8S-YAML

一、Kubernetes对象的描述 kubernetes中资源可以使用YAML描述(如果您对YAML格式不了解,可以参考YAML语法),也可以使用JSON。其内容可以分为如下四个部分: typeMeta:对象类型的元信息,声明对象…

Python爬虫从入门到入狱系列合集

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉&…