Go中间件

本文详细介绍了Gin框架中的中间件概念和应用,包括全局中间件和路由中间件的创建与使用。通过示例展示了如何自定义中间件进行用户认证和session管理,并解释了中间件的流转机制,如Next()和Abort()函数的作用。文章还讨论了中间件在处理请求过程中的业务逻辑控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简述

gin中间件类似java的拦截器,通过中间件可以在处理具体的route请求时,提前做一些业务。比如用户有效性的校验,特定日志格式的打印,错误日志的打印等等。

一个个中间件组成一条中间件链,对HTTPRequest请求进行拦截处理,实现了代码的解耦和分离,并且中间件之间相互不用感知到,每个中间件只需要处理自己需要处理的事情即可。

gin的中间件大致可以分为两类,全局中间件和路由中间件,下面记录gin的中间件学习过程中的一些问题。

  • 全局中间件
  • Group 中间件
  • 单个路由中间件

二、全局中间件

1、默认中间件

使用router := gin.Default()定义route时,默认带了Logger()Recovery()。我们可以使用BasicAuth()中间件做一些简单的用户权限的认证

// Default returns an Engine instance with the Logger and Recovery middleware already attached.

func Default() *Engine {

   debugPrintWARNINGDefault()

   engine := New()

   engine.Use(Logger(), Recovery())

   return engine

}

gin的中间件是通过Use方法设置的,它接受一个可变的参数,所以我们可以设置多个中间件

// Use adds middleware to the group, see example code in GitHub.

func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes {

   group.Handlers = append(group.Handlers, middleware...)

   return group.returnObj()

}

一个gin的中间件,其实就是一个HandleFunc

router.GET("/", func(c *gin.Context) {

    c.JSON(200"首页")

})

后边的func(c *gin.Context) {}就是一个HandleFunc

2、自定义中间件

func main() {

   // 初始化环境

   initCtx, cancel := context.WithCancel(context.Background())

   defer cancel()

   //加载服务配置

   bjh.InitServicer(initCtx)

   // 默认中间件引擎

   router := gin.Default()

   router.Use(bjh.LoginAuth())

   router.GET("/", func(c *gin.Context) {

   })

   _ = router.Run(":8000")

}

go get gopkg.in/cas.v1

func LoginAuth() gin.HandlerFunc {

   return func(ctx *gin.Context) {

      transCfg := &http.Transport{

         TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 不验证证书

      }

      client := &http.Client{Transport: transCfg}

      u, _ := url.Parse(uuap.AuthInterface)

      newClient := cas.NewClient(&cas.Options{URL: u, Client: client})

      h := newClient.HandleFunc(func(w http.ResponseWriter, r *http.Request) {

         ticket := r.FormValue("ticket")

         devtools.Log("ticket--------1", ticket)

         if ticket == "" || !cas.IsAuthenticated(r) {

            cas.RedirectToLogin(w, r)

            devtools.Log("redirect""go out")

            ctx.Abort()

            return

         }

         _, _ = fmt.Fprintf(w, "Hello %s\n", cas.Username(r))

         devtools.Log("ticket--------2", ticket)

      })

      h.ServeHTTP(ctx.Writer, ctx.Request)

      ctx.Next()

   }

}

示例:

获取请求中的sessionid,写入到context中,context.Next()跳到下一个中间件中,下一个中间件会对这个session进行有效性校验(sessionid是否存在,是否过期等)

//用户身份认证中间件

func Validate() gin.HandlerFunc {

 return func(context *gin.Context) {

 // 参数的或者以及部分业务逻辑

 var sessionid = ""

 cookie, err := context.Request.Cookie(defs.Cookie_key)

 if err == nil && cookie != nil {

 sessionid = cookie.Value

 else {

 sessionid = session.GenerateSess(login.UserName)

 }

 context.Set("sessionid", sessionid)

 context.Next()

 return

 }

}

3、路由中间件

只是针对具体的路由规则

示例:

下面定义了一个分组路由/user,分组路由下的/login需要验证用户名和密码,这个路由使用的是路由中间件Validate(),通过查库验证用户名和密码。而其余的路由/manager/show/manager/modify使用了路由中间件handles.Cookie(),这个中间件验证用户在登陆成功后的sessionid的有效性

// 设置user路由组

{

 userGroup := router.Group("/user")

 {

 //userGroup.Use(handles.AccessJsMiddleware())

 //显示用户登录主页

 userGroup.GET("/show", handles.ShowUserLogin())

 //用户登录

 userGroup.POST(

 "/login",

 handles.Validate(), //用户密码有效性验证

 handles.HandleUserLogin())

 //用户管理

 userGroup.GET("/manager/show", handles.Cookie(), handles.ShowUserManager())

 userGroup.POST("/manager/modify", handles.Cookie(), handles.HandleUserOperte())

 }

}

三、中间件件的流转

gin提供了两个函数Abort()Next(),配合着return关键字用来跳转或者终止存在着业务逻辑关系的中间件。

.Next()

跳过当前的中间件,执行下一个中间件,待下一个中间件执行完后再回到当前next位置,执行后面的逻辑

.Abort()

终止该中间件的流程,如果不return的话会继续执行后面的逻辑,但不再执行其他的中间件

结论

1. next()函数会跳过当前中间件中next()后的逻辑,当下一个中间件执行完成后再执行剩余的逻辑

2. abort()函数执行终止当前中间件以后的中间件执行,但是会执行当前中间件的后续逻辑

使用 Go 处理中间件 - 知乎

Gin框架系列03:换个姿势理解中间件 - Go语言中文网 - Golang中文社区

golang gin 中间件,返回结果 - 漫步的影子 - 博客园

gin使用中间件出错后不能用return终止,而应该使用Abort实现_katy的小乖的博客-优快云博客

使用 Go 处理中间件 - SegmentFault 思否

### Golang 中间件实现与使用教程 #### 定义中间件概念 在Web开发框架中,中间件是指位于服务器接收请求和发送响应之间的函数。这些函数可以在请求到达最终处理器之前对其进行预处理,在响应返回给客户端前进行后置处理[^1]。 #### Gin 框架中的中间件特性 对于采用Gin框架的应用程序来说,中间件提供了一种灵活的方式来增强HTTP路由的功能而不必修改核心业务逻辑代码。利用中间件能够轻松加入诸如身份验证、访问控制、日志记录等功能模块到应用程序之中[^2]。 #### 创建自定义中间件实例 下面展示了一个简单的基于时间戳的日志记录器作为Gin中间件的例子: ```go func Logger() gin.HandlerFunc { return func(c *gin.Context) { t := time.Now() // 设置变量来存储当前的时间戳 c.Set("request-time", t) // 处理请求 c.Next() // 记录并打印执行耗时 log.Printf("%s\t%s\t%s\n", c.Request.Method, c.Request.URL.Path, time.Since(t)) } } ``` 此段代码创建了一个名为`Logger()` 的函数,它返回一个实现了 `gin.HandlerFunc` 接口的方法。当该方法被调用时会先获取当前时刻,并将其存入上下文中;接着继续传递控制权至下一个处理器(`c.Next()`);最后计算整个过程所花费的时间并将信息输出到标准错误流上。 #### 注册全局或局部中间件 要使上述编写的中间件生效,则需注册它们成为应用的一部分。可以通过两种方式完成这一步骤——要么是在启动服务端的时候设置成全局性的(即应用于所有的路由),要么针对特定路径单独指定局部使用的中间件。 ##### 全局中间件配置示例: ```go router.Use(Logger(), Recovery()) ``` 这里假设还存在另一个用于捕获异常恢复的服务`Recovery()` ,两者共同作用于所有API接口之上。 ##### 局部中间件配置示例: ```go auth := router.Group("/admin", AuthRequired()) { auth.GET("/dashboard", GetDashboard) } ``` 在这个例子中,只有以 `/admin` 开头的URL才会受到鉴权机制的影响。 #### 学习更多有关GoLang中间件的知识 除了官方文档外,网络上有许多优质的第三方资料可以帮助开发者深入了解这一主题。例如,“golang stats api handler”的开源项目提供了关于性能统计方面的实用工具集,可能对某些场景下的监控需求有所启发[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值