Les responsabilités du middleware Golang sont enfichables et autonomes. Ses fonctions sont : 1. Dans le processus de traitement des demandes, intercepter, traiter ou filtrer les demandes, et peut le faire avant et après le traitement des demandes. Certaines opérations, telles que la journalisation, l'authentification, le traitement des paramètres de demande, etc. ; 2. Le middleware peut séparer la logique métier et le traitement des demandes dans la structure du code, rendant le code plus clair et plus facile à maintenir. 3. Le middleware peut être réutilisé, réduisant ainsi la charge de travail ; d'écriture répétée de code.
L'environnement d'exploitation de ce tutoriel : système windows10, GO version 1.20. 1, ordinateur Dell G3.
Le rôle du middleware Golang
La principale responsabilité du middleware est d'être enfichable et autonome. Pendant le processus de traitement de la demande, la demande est interceptée, traitée ou filtrée, et certaines opérations peuvent être effectuées avant et après le traitement de la demande, telles que la journalisation, l'authentification, le traitement des paramètres de la demande, etc. Le middleware peut séparer la logique métier et le traitement des demandes dans la structure du code, rendant le code plus clair et plus facile à maintenir. Dans le même temps, les middlewares peuvent être réutilisés, réduisant ainsi la charge de travail liée à l’écriture répétée de code.
L'exemple de code est le suivant :
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 }
Quand Handle est-il appelé ?
Jetons un coup d'œil au code source de 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 }
Nous pouvons probablement voir à partir de ce code : BaseMiddleware est en fait une liste chaînée de middleware de nœuds qui forme une liste chaînée , et il existe différents middlewares de groupe et middlewares ordinaires. Le middleware à appeler est décidé en fonction de l'étape de traitement actuelle de ctx. Enfin, le gestionnaire de ctx est appelé
Le middleware personnalisé doit hériter de BaseMiddleware. # #
Et implémenter le handlefunc (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) } }
# #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 }
La valeur du signe dans l'en-tête transmis doit être cohérente avec le md5 de la SecretKey dans le fichier de configuration uri +
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!