Home> Common Problem> body text

What is the role of golang middleware?

尊渡假赌尊渡假赌尊渡假赌
Release: 2023-05-26 11:03:35
Original
2174 people have browsed it

The responsibilities of Golang middleware are pluggable and self-sufficient. Its functions are: 1. In the process of processing requests, it intercepts, processes or filters requests, and can perform some operations before and after processing requests. , such as logging, authentication, processing request parameters, etc.; 2. Middleware can separate business logic and processing requests in the code structure, making the code clearer and easier to maintain; 3. Middleware can be reused, reducing Reduce the workload of repeated code writing.

What is the role of golang middleware?

The operating environment of this tutorial: Windows 10 system, GO version 1.20.1, Dell G3 computer.

The role of Golang middleware

The main responsibility of middleware is to be pluggable and self-sufficient. During the process of processing the request, the request is intercepted, processed or filtered, and some operations can be performed before and after processing the request, such as logging, authentication, processing request parameters, etc. Middleware can separate business logic and request processing in the code structure, making the code clearer and easier to maintain. At the same time, middleware can be reused, reducing the workload of repeated code writing.

The code example is as follows:

package main import ( "fmt" "github.com/devfeel/dotweb" ) func main() { app := dotweb.New() // App注册中间件 app.Use(NewSessionAuth()) // 开启SESSION app.HttpServer.SetEnabledSession(true) // 设置路由 输出字符串 Hello Dotweb app.HttpServer.GET("/", func(ctx dotweb.Context) error { method := ctx.Request().Method return ctx.WriteString("Hello Dotweb\n" + "Method:" + method) }) //开启服务 端口号 fmt.Println("dotweb.StartServer => 8080") err := app.StartServer(8080) fmt.Println("dotweb.StartServer error => ", err) } // SessionAuth 结构体 type SessionAuth struct { dotweb.BaseMiddlware } // Handle 处理程序 func (m *SessionAuth) Handle(ctx dotweb.Context) error { fmt.Println("SessionID = ", ctx.SessionID(), " RequestURI = ", ctx.Request().RequestURI) return m.Next(ctx) } // NewSessionAuth New func NewSessionAuth() *SessionAuth { sAuth := new(SessionAuth) return sAu }
Copy after login

When is Handle called?

Let’s take a look at the source code of BaseMiddlWare:

// BaseMiddleware is the base struct, user defined middleware should extend this type BaseMiddleware struct { next Middleware excludeRouters map[string]struct{} } func (bm *BaseMiddleware) SetNext(m Middleware) { bm.next = m } func (bm *BaseMiddleware) Next(ctx Context) error { httpCtx := ctx.(*HttpContext) if httpCtx.middlewareStep == "" { httpCtx.middlewareStep = middleware_App } if bm.next == nil { if httpCtx.middlewareStep == middleware_App { httpCtx.middlewareStep = middleware_Group if len(httpCtx.RouterNode().GroupMiddlewares()) > 0 { return httpCtx.RouterNode().GroupMiddlewares()[0].Handle(ctx) } } if httpCtx.middlewareStep == middleware_Group { httpCtx.middlewareStep = middleware_Router if len(httpCtx.RouterNode().Middlewares()) > 0 { return httpCtx.RouterNode().Middlewares()[0].Handle(ctx) } } if httpCtx.middlewareStep == middleware_Router { return httpCtx.Handler()(ctx) } } else { // check exclude config if ctx.RouterNode().Node().hasExcludeMiddleware && bm.next.HasExclude() { if bm.next.ExistsExcludeRouter(ctx.RouterNode().Node().fullPath) { return bm.next.Next(ctx) } } return bm.next.Handle(ctx) } return n }
Copy after login

Through this code we can probably see that BaseMiddleware is actually a linked list of node middleware that forms a linked list, and has different types, including Group middleware and ordinary middleware, decide which middleware to call based on the current processing step of ctx, and finally call the handler of ctx

The custom middleware must inherit BaseMiddleware

and implement the handle

func (asm *ApiSignMiddleware) Handle(ctx dotweb.Context) error { if sign := ctx.Request().QueryHeader("Sign"); len(sign) <= 0 { return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil}) } else { uri := ctx.Request().RequestURI if index := strings.Index(uri, "?"); index != -1 { uri = uri[:index] } if ok := checkSign(sign, uri); !ok { return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil}) } return asm.Next(ctx) } }
Copy after login

This way you can parse the incoming Contex

Analyze the middleware used in blogserver:

CrosMiddleware

func (cm *CrosMiddleware) Handle(ctx dotweb.Context) error { if strings.Contains(ctx.Request().RequestURI, "v1") && ctx.Request().Method != "OPTIONS" { if sign := ctx.Request().QueryHeader("Sign"); len(sign) <= 0 { return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil}) } else { uri := ctx.Request().RequestURI if index := strings.Index(uri, "?"); index != -1 { uri = uri[:index] } if ok := checkSign(sign, uri); !ok { return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil}) } return cm.Next(ctx) } } return cm.Next(ctx) }
Copy after login
CrosMiddleware 对uri的非参数部分调用checkSign
Copy after login
//验证签名 (requestUri(不含query)+secret) func checkSign(sign, uri string) bool { result := utils.Md5(uri + config.Config().SecretKey) return result == sign }
Copy after login

The passed header The sign value inside should be consistent with the SecretKey md5 in the uri configuration file

The above is the detailed content of What is the role of golang middleware?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author