Golang Gin middleware Next() method

Next() method


  • Calling the next() method in the middleware will jump to the Handler function from the place where the next() method is called
  • The execution of the Handler function is completed. If there is still some code in the middleware that has not been executed ( the code after next() in the middleware), execute the code

If the first middleware processing directly uses the next function, jump directly to the handler function, and return to process the remaining middleware functions after processing.

 

Except for the most central piece, everything else is middleware. When a middleware comes in, when I use next directly, I jump directly to the handler of the business processing part, and after the handler of the business processing is finished, then it Then jump back to the middleware code that has not been processed layer by layer.

So it is very like an onion. In fact, the middleware is layer by layer, but only half of it is executed before. After processing the middleware, it responds. When responding, it will process the remaining middleware layer by layer. layer.

// 日志中间件
func MiddleWareLog() gin.HandlerFunc {
	//这里也是context,因为你的中间件也是对请求和响应的处理,只要涉及到请求和响应的处理就用到context上下文
	return func(c *gin.Context) {
		fmt.Println("log start")
		c.Next()
		fmt.Println("log end")
	}
}

func MiddleWareRequestId() gin.HandlerFunc {
	return func(c *gin.Context) {
		fmt.Println("request id start")
		c.Next()
		fmt.Println("request id end")
	}
}


func main() {
	r := gin.Default()
	r.Use(MiddleWareLog(), MiddleWareRequestId())
	r.GET("/", func(c *gin.Context) {
		fmt.Println("app handler.......")
		c.JSON(http.StatusOK, gin.H{
			"msg": "success",
		})
	})
	r.Run(":8000")
}

                                      
[GIN-debug] Listening and serving HTTP on :8000
log start
request id start
app handler.......
request id end
log end
[GIN] 2023/04/08 - 09:51:03 | 200 |      2.2505ms |             ::1 | GET      "/"

First of all, you can see that I first registered the log middleware, and then registered the id of the requestid middleware. So it comes in the order of registering middleware, and then it will be executed.

(1) If the above middleware does not add the next function, then it will execute all the logic in the middleware

(2) If there is only one layer of middleware, calling the next() method in the middleware will jump to the Handler function from where the next() method is called .

If there are multiple layers of middleware, it will jump to the next middleware in the linked list, and the above is to jump from the log middleware to the request middleware. The next function is executed in the requestid middleware, there is no middleware under it, only the business code, then execute the business handler, and after the execution is completed, I return, and finally execute the rest of the middleware that has not been executed logic.

In fact, like an onion, the outermost layer is executed first, and the innermost layer is executed last. But after the business code is executed, I start from the innermost layer

Business scenario: The middleware at the innermost layer is requestid. You can do a start timing, next() and then execute the business code inside. The execution time of this method.

When writing some micro-service frameworks and making a metric display, it is actually done with the help of middleware, and then the data is exposed to an interface, and then Prometheus fetches it, and finally displays it. This is how it is realized.

 

Implement token authentication


  • http://127.0.0.1:8080/index The home page of index can be directly accessed without token
  • http://127.0.0.1:8080/home The home directory needs to verify the token , and the verification can only be accessed

 

The maximum storage length of middleware is more than 60, and it cannot be stored any further.

c.abort() is to jump directly to the last one of the linked list, if there is nothing behind, then it will be executed, and other middleware will not be executed.

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

func AuthMiddleWare() gin.HandlerFunc {
	return func(c *gin.Context) {
		//常用场景,客户端也就是接口的调用方,客户端携带token的方式 1:请求头(最常用) 2:请求体 3:uri
		token := c.Request.Header.Get("token")
		fmt.Println("获取token信息:", token)

		if token != "qazw1234" {
			c.JSON(http.StatusOK, gin.H{
				"msg": "身份验证不通过",
			})
			//Abort方法用于跳到handler链表最后一个index,相当于直接退出,不执行后面的handler了
			c.Abort()
            return
		}
	}
}

func main() {
	r := gin.Default()
	r.GET("/home", AuthMiddleWare(), func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"msg": "home路由",
		})
	})
	r.Run(":8000")
}

おすすめ

転載: blog.csdn.net/qq_34556414/article/details/130024569
おすすめ