久々にPlay frameworkをチェックしてみたら2.6になっていた上にactivatorからsbtに簡素化されていて良さを感じたので久々に弄ってみた。
簡単なFormを作成してそれを投げるプログラムを書いてみたところ、ただのPOSTリクエストなのにUnauthorizedと怒られてしまったので調査した。

1.原因

どこのバージョンからかは不明だが、どうもPlay frameworkはデフォルトでCSRF対策をしているため、CSRFトークンを伴わないPOSTリクエストはデフォルトではUnauthorizedなリクエストとして弾かれることになっているらしい。

2.対応方法

対応方法として考えられるのは (1)CSRF対策の無効化、および (2)CSRF対策を仕込む、の2つだろう。それぞれ以下のようにすることで実現できる。

(1) CSRF対策の無効化

application.confに

play.filters.disabled+=play.filters.csrf.CSRFFilter
を追加するとデフォルトで噛まされているCSRF-Filterが外れる。 ただ、本番環境なんかでやるのはセキュリティ上あまり好ましくはないので推奨されないだろう。

Playの練習をする場面くらいにとどめておくべきアプローチではないだろうか。

(2) CSRF対策を仕込む

公式ドキュメントでも「いろんなアプローチがあるよね」とか紹介されているわけだけど、最も簡便な方法として、URL末尾にCSRFトークンを追加する方法をここでは紹介する。

  1. 何らかの方法でViewに対してRequestHeaderを受け渡す
    最も簡便な方法はViewの引数をカリー化して末尾にRequestHeaderを受け取るimplicitな引数を追加する方法。
  2. 受け取ったRequestHeaderとroutesを用いてCSRFトークン付きのURLを生成する
    helper.CSRFを利用する。CSRFはimplicitにRHを受け取るので、1.でRHをimplicitにしていた場合、helper.CSRF(route)で得られる。
  3. このURLに対してPOSTリクエストを発行するようにする

3. その他

詳しくは公式ドキュメントを読もう。
(日本語版は2.4までしかないんだよねぇ・・・)

参考