Road To Nowhere

主にWebまわりのエンジニア的なお仕事に関するようなことのあれこれ。

Symfony2のログインに関するメモ

Symfony2で会員登録機能を開発していてハマったことがあったのでメモ。


Symfony2のセキュリティ機能はけっこう素晴らしくて簡単にログイン機能(ユーザーの認証と承認)を使うことができる。
セキュリティ | Symfony2日本語ドキュメント
このページをじっくり読みながらやればそれほど困ることはないと思う。


今回ハマったのは会員登録機能を開発しているときのこと。
ユーザーが会員登録のステップを終了した後、ログインフォームを経由せずにログインした状態にしてマイページへ遷移するという実装をしたかった。
このやり方がなかなか見つからなかったが、ようやく英語でいくつか発見。
Symfony2: How to log user manually? - Stack Overflow
php - Automatic post-registration user authentication - Stack Overflow
(最近、stackoverflowがよく検索にひっかかっるな)

$securityContext = $this->get('security.context');
$token = new UsernamePasswordToken($userEntity, null, 'secured_area', $roles);
$securityContext->setToken($token);

実際に実装したのはこんな感じ。
詳しくは英語で書いてあるけどいちおう注意点を言っておくと、UsernamePasswordToken()の2番目の引数はnullでOK。3番目の引数は'secured_area'はsecurity.ymlのfirewallsで設定している文字列。このドキュメントの例にならっているのであれば'secured_area'でOKだった。


2012/2/17、symfony2 ver2.0.10で再検証したところ、上記対応でセッションが永続されたので以下の対応不要です。
バージョンアップの影響から以前の検証方法が悪かったのかは調べていません。

さて、これで確かにログイン状態にすることはできたのだが、どこか他のページに遷移するとログイン状態を維持できない。
まさかセッションにuserのidをもっておいて毎ページで上記の処理をするわけにもいかないので調査続行。
最終的には上記のsetTokenのあと、下記のようにセッションに$tokenを保存してやれば、ログイン状態を維持できた。

$request = $this->getRequest();
$session = $request->getSession();
$session->set('_security_secured_area', serialize($token));

'_security_secured_area'の「secured_area」の文字列は、こちらも上と同様、security.ymlのfirewallsで設定している文字列。


調査にけっこう時間とられてしまったので、覚えておくと幸せになれるかも。