CSRF token is invalid. | PHPer Tips

PHPer Tips

日本語の情報が少ないPHPフレームワークSymfony2を中心とした話題を集めています。

CSRF token is invalid.

Symfony2で開発を進めていて、formオブジェクトにあるisValidを使って($form->isValid())、上記のエラーに遭遇したことありませんか?

このブログの読者で、さすがにCSRFってなに? って人はそんなにいないと思いますが、(いたら、とりあえずぐぐってみてください)
CSRF tokenなんて埋めてないよって、戸惑う人は結構いるかもしれません。

Symfony2では、備え付けのform機能($form->createViewなど)を使うと、自動的にCSRF対策をしてくれます。

frontに送られているformオブジェクトにtokenが含まれているわけです。

twigで、{{form_widget(form)}} のように全要素を一度に呼び出した場合は、良いのですが、問題は、
以下のように個別に表示させた場合です。
{{form.name}}
{{form.address}}

UIの都合上、上記のようにしたい場合も多いでしょう。
しかし、この場合、formオブジェクトに埋め込まれているCSRF tokenがPostされません。
そこで、Model上にて、$form->isValid() を実行すると、falseとなってしまいます。
$form->getErrors() を見ると、表題のエラーが出ていると思います。

これを改善するには、

{{form._token}}をtwigに埋め込んでやる必要があります。

あるいは、{{form_rest(form)}}でもOKです。
ただし、この場合、form_widgetで表示していない残りすべての項目がレンダリングされますのでご注意。

また、Ajaxなどを使用してPostしたものを受け取って $form->isValid()する場合に、備え付けのCSRF機能ではなく、独自のキーを渡すこともあると思いますが、その場合は、form_typeのオプションで以下のように機能を停止する必要があります。

public function getDefaultOptions(array $options)
{
return array(
'csrf_protection' => false,
);
}