発端
Go言語の高パフォーマンスWAFであるEchoを利用したアプリを開発している際、 特定のクエリパラメータ値が一致しなけれ処理を通さない という要件があった。各ルート以下でいちいちQueryParamをvalidするのも馬鹿らしく、なんとかしてミドルウェアと模索した結果、割と簡単に出来たのでメモ程度に共有。
echoのmiddleware
expressよろしくnext
で繋いでいくスタイルらしい。そんなわけで下記コード。
main.go
package main
import (
"net/http"
"os"
"github.com/labstack/echo"
"github.com/labstack/echo/engine/standard"
"github.com/labstack/echo/middleware"
)
// CustomMiddleware
func CustomMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// QueryParam ?hoge=にあるパラメータを取得
hoge := c.QueryParam("hoge")
if hoge != os.Getenv("hoge") {
// 一致してなければUnauthorizedを返す(ステータスは適当)
return echo.NewHTTPError(http.StatusUnauthorized)
}
return next(c)
}
}
func main() {
e := echo.New()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
// 自作ミドルウェアをグループ化
m := e.Group("", CustomMiddleware)
// グループに適用させるルーティング
m.GET("/", func(c echo.Context) error {
return c.Render(http.StatusOK, "index", "HOGEHOGE")
})
m.POST("api/v1/upload", Upload)
m.GET("api/v1/download", Download)
// App Server Run
e.Run(standard.New(":" + os.Getenv("PORT")))
}
これで想定どおりに動いた。コツはGroup
のmiddlewareとして動作させることで、単純にe.Use(...)
とかやると全体にかかりすぎて、htmlやcssといったstaticなコンテンツの取得にまで影響してしまった。あくまでもルーティングパスのみに掛けること。