Home  >  Article  >  What is the role of golang middleware?

What is the role of golang middleware?

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌Original
2023-05-26 11:03:352204browse

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
}

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
}

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)
    }
}

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)
}
 CrosMiddleware 对uri的非参数部分调用checkSign
//验证签名 (requestUri(不含query)+secret)
func checkSign(sign, uri string) bool {
    result := utils.Md5(uri + config.Config().SecretKey)
    return result == sign
}

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!

Statement:
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