標準ライブラリのhttpパッケージだけでもmiddlewareは簡単に作れますよ、というお話。
おさらい: http.Handlerまたはhttp.HandlerFuncでやり取りする
Goのhttp.Handlerやhttp.HandlerFuncをちゃんと理解する - oinume journalに書いたとおり、
- http.ListenAndServe
- ServeMux.Handle
に渡すのは http.Handler
なので、何かしらのmiddlewareもこのinterfaceを満たすことを考えればよい。もしくは ServeMux.HandleFunc
を使うのであれば http.HandlerFunc
を使うでもよし。
middlewareはhttp.Handlerを引数に取り、http.Handlerを返す
例えば、 admin
という名前のCookieを持っていないとアクセスできないようなmiddlewareを考えてみる。
func requireAdminCookie(h http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { _, err := r.Cookie("admin") // Check `admin` cookie if err != nil { http.Error(w, "No admin cookie", http.StatusForbidden) return } h.ServeHTTP(w, r) } return http.HandlerFunc(fn) }
こんな感じで、h.ServeHTTP
を呼ぶ前にCookieがあるかをチェックする処理を入れる。
このmiddlewareを使って、「特定のURLはadmin cookieがないとアクセスできないようにする」ためには、以下のようにmiddlewareと実際のHandlerを組み合わせる必要がある。以下のコードだと /admin
のURLはCookieがないと403 Forbiddenが返される。
func main() { mux := http.NewServeMux() mux.Handle("/admin", requireAdminCookie(http.HandlerFunc(handleAdmin))) if err := http.ListenAndServe(":8080", mux); err != nil { log.Fatal(err) } } // responseを返すHandler func handleAdmin(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) fmt.Fprint(w, "This is admin page") }
参考リンク
- 作者: 松木雅幸,mattn,藤原俊一郎,中島大一,牧大輔,鈴木健太,稲葉貴洋
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/09
- メディア: 大型本
- この商品を含むブログ (4件) を見る