クラウド時代のWebアプリケーション・スマートフォンアプリを開発・運用する会社です。 03-4577-8680 03-6673-4950

Go のフレームワーク echo でCSRFミドルウェアを使う(2)結果を取り出す

2017-08-20

「Go のフレームワーク echo でCSRFミドルウェアを使う」シリーズ第2弾です。

ミドルウェアが指定されている場合、基本的には、ハンドラーが実行される前に実行されます。

ですのでたとえば、CSRFミドルウェアによって不正と判断された場合には、URLに割り当てられたハンドラー処理をスキップし、ルーターから直接、クライアントへ結果が返却されることになります。

しかしこの場合に、具体的にどのような結果が返るのか、ということはリファレンスには記載されていません。

ということで今回もソースを追っていきましょう。

…と言っても、今回は非常に単純な話で終わってしまうのですが…。

該当のソースはここです。
https://github.com/labstack/echo/blob/master/middleware/csrf.go#L142

ここで書かれているのはつまり:

送信されたトークンが不正であった場合 -> http.StatusBadRequest(=400)

トークンが一致しなかった場合 -> http.StatusForbidden(=403)

というように、HTTPレスポンスヘッダがセットされるということですね。

さて、これをルーター内でキャッチするには、e.HTTPErrorHandlerを使用することになります。

例えば次のような形になりますね。

e := echo.New()
e.Use(middleware.CSRF())
e.POST(“/foobar”, handler_foobar)
e.HTTPErrorHandler = func(err error, c echo.Context) {
if h, ok := err.(*echo.HTTPError); ok {
switch h.Code {
case http.StatusBadRequest:
// 400
case http.StatusForbidden:
// 403
default:
// その他
}
}
}

もし、BadRequestやForbiddenが他のミドルウェアなどでも発生しうる場合、BadRequestである場合は別として、もし「(開発中の確認作業として)ForbiddenがCSRFミドルウェア由来のものであるか否かを確認したい」という状況はありえるかもしれません。

その場合、err.Error()の中身にはInvalid csrf token文字列が入りますので、ログに出せば確認可能かと思います。

これをクライアント側で確認できるようにしたいと考えた場合、エラーメッセージそのものを条件判別に使うのは危険(echoのバージョンアップでメッセージが変わることは十分ありうる)と思いますので、開発用のHTTPヘッダにerr.Error()の中身を載せて返す、などという方が妥当であるものと思います。