golang gin 中常用中間件


在Gin的整個實現中,中間件可謂是Gin的精髓。一個個中間件組成一條中間件鏈,對HTTP Request請求進行攔截處理,實現了代碼的解耦和分離,並且中間件之間相互不用感知到,每個中間件只需要處理自己需要處理的事情即可。 Gin中常用的中間件是:

Logger 日志

Recovery panic 處理 返回500
BasicAuth  基本認證

Gin默認中間件

在Gin中,我們可以通過Gin提供的默認函數,來構建一個自帶默認中間件的*Engine

r := gin.Default()

Default函數會默認綁定兩個已經准備好的中間件,它們就是Logger 和 Recovery,幫助我們打印日志輸出和painc處理。
func Default() *Engine {
    debugPrintWARNINGDefault()
    engine := New()
    engine.Use(Logger(), Recovery())
    return engine
}

從中我們可以看到,Gin的中間件是通過Use方法設置的,它接收一個可變參數,所以我們同時可以設置多個中間件。

func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes

到了這里其實我們應該更加明白了,一個Gin的中間件,其實就是Gin定義的一個HandlerFunc,而它在我們Gin中經常使用,比如:

r.GET("/", func(c *gin.Context) {
        fmt.Println("首頁")
        c.JSON(200, "")
    })

后面的func(c *gin.Context)這部分其實就是一個HandlerFunc

在Gin中,為我們提供了gin.BasicAuth幫我們生成基本認證的中間件,方便我們的開發。

r := gin.Default()

    r.Use(gin.BasicAuth(gin.Accounts{
        "admin": "123456",
    }))

    r.GET("/", func(c *gin.Context) {
        c.JSON(200, "首頁")
    })

    r.Run(":8080")

我們添加一個用戶名為admin,密碼是123456的賬戶,用於HTTP 基本認證。現在我們運行啟動,訪問http://localhost:8080/,這時候只有我們輸入正確的用戶名和密碼,才能看到首頁,否則是看不到的,這樣我們就達到了授權的目的,就是這么簡單。

針對特定URL的Basic Authorization

其實在實際的項目開發中,我們基本上不太可能對所有的URL都進行認證的,一般只有一些需要認證訪問的數據才需要認證,比如網站的后台,那么這時候我們就可以用分組路由來處理。

func main() {
    r := gin.Default()

    r.GET("/", func(c *gin.Context) {
        c.JSON(200, "首頁")
    })

    adminGroup := r.Group("/admin")
    adminGroup.Use(gin.BasicAuth(gin.Accounts{
        "admin": "123456",
    }))

    adminGroup.GET("/index", func(c *gin.Context) {
        c.JSON(200, "后台首頁")
    })

    r.Run(":8080")
}

現在我們運行訪問/首頁是可以正常顯示的,但是我們訪問/admin/index會提示輸入密碼,其實所有/admin/*下的URL都會讓輸入密碼才能訪問,這就是我們分組路由的好處,我們通過把中間件加到/admin這個分組路由上,就可以達到我們的目的。

通過分組路由的控制,我們可以比較靈活的設置HTTP認證,粒度可以自己隨意控制。

自定義中間件

我們已經知道,Gin的中間件其實就是一個HandlerFunc,那么只要我們自己實現一個HandlerFunc,就可以自定義一個自己的中間件。現在我們以統計每次請求的執行時間為例,來演示如何自定義一個中間件。

func costTime() gin.HandlerFunc {
    return func(c *gin.Context) {
        //請求前獲取當前時間
        nowTime := time.Now()

        //請求處理
        c.Next()

        //處理后獲取消耗時間
        costTime := time.Since(nowTime)
        url := c.Request.URL.String()
        fmt.Printf("the request URL %s cost %v\n", url, costTime)
    }
}

以上我們就實現了一個Gin中間件,比較簡單,而且有注釋加以說明,這里要注意的是c.Next方法,這個是執行后續中間件請求處理的意思(含沒有執行的中間件和我們定義的GET方法處理),這樣我們才能獲取執行的耗時。也就是在c.Next方法前后分別記錄時間,就可以得出耗時。

有了自定義的中間件,我們就可以這么使用。

func main() {
    r := gin.New()

    r.Use(costTime())

    r.GET("/", func(c *gin.Context) {
        c.JSON(200, "首頁")
    })

    r.Run(":8080")
}

現在啟動程序,在瀏覽器里打開就可以看到如下日志信息了。

the request URL / cost 26.533µs

通過自定義中間件,我們可以很方便的攔截請求,來做一些我們需要做的事情,比如日志記錄、授權校驗、各種過濾等等。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM