首頁  >  文章  >  golang中間件有什麼作用

golang中間件有什麼作用

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌原創
2023-05-26 11:03:352203瀏覽

Golang中間件的責任是可插拔且自足,其作用是:1、在處理請求的過程中,對請求進行攔截、處理或過濾,並且可以在處理請求的前後進行一些操作,例如日誌記錄、身份驗證、處理請求的參數等;2、中間件可以在程式碼結構上實現業務邏輯和處理請求的分離,使得程式碼更加清晰和易於維護;3、中間件可以被重複使用,減少了程式碼重複編寫的工作量。

golang中間件有什麼作用

本教學操作環境:windows10系統、GO 1.20.1版本、Dell G3電腦。

Golang中間件的作用

中間件主要責任就是可插拔且自足。在處理請求的過程中,對請求進行攔截、處理或過濾,並且可以在處理請求的前後進行一些操作,例如日誌記錄、身份驗證、處理請求的參數等。中間件可以在程式碼結構上實現業務邏輯和處理請求的分離,使得程式碼更加清晰和易於維護。同時,中間件可以重複使用,減少了程式碼重複編寫的工作量。

程式碼範例如下:

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
}

Handle是什麼時候被呼叫的?

我們看看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
}

透過這個程式碼我們大概能看出:BaseMiddleware其實是一個鍊錶的node中間件組成了一個鍊錶,並且有不同的類型,有group中介軟體和普通中間件,根據目前ctx所處的處理步驟決定呼叫哪一個中間件,最後呼叫ctx的handler

自訂的middleware要繼承BaseMiddleware

並且實作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)
    }
}

這樣就可以對傳進來的Contex進行解析

分析blogserver裡面用到的middleware:

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
}

傳過來得header裡面得sign值應該跟uri 設定檔裡面的SecretKey取md5一致

以上是golang中間件有什麼作用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn