symfonyのユーザ自動ログアウトとセッションタイムアウトについて

これは僕がアホというか、単純にわかってなかっただけの話なのですが。

symfonyでは一定時間経つとユーザをログアウトさせるという設定が可能です。アプリケーションのfactories.ymlでuserのパラメータにtimeoutという値が設定でき、そこに秒数を指定するとできるようになります。

sfBasicSecurityUserクラスのinitialize()メソッドの中で、現在の時間と最終アクセス時の差分が設定したtimeoutよりも大きい場合、自動的にログアウトする処理を行っています。

その際にiniのsession.gc_maxlifetimeという値をユーザの自動ログアウトと同じ時間に設定しています。

session.gc_maxlifetimeという設定はセッションをクリアするまでの秒数を設定するものなのですが、てっきりここでセッションの有効時間もちゃんと設定してくれてすごいなあとか思っていたのですが、全然違いました。

timeout オプションはユーザー認証のタイムアウトを定義します。これはセッションのタイムアウトとは関係ありません。デフォルトの設定は30分間何もしていないユーザーの認証を自動的に解除します。

symfony 1.x legacy website

当然なんですよね、これ。PHPがセッションのGCを行うのはsession_start()を実行したタイミングです。symfonyのデフォルトでは、session_start()はsfSessionStorageクラスが生成されたタイミングで行うのですが、それはUserクラスを生成するより前で行われています。そこまでの間、symfonyはsession.gc_maxlifetimeの設定を変更したりしていません。

つまり、.htaccessなどで変更していない限りはphp.iniで設定されているsession.gc_maxlifetimeの時間でセッションがクリアされるわけです。

じゃあuserのtimeoutは何かっていうと、ドキュメントにもあるとおり、あくまで「ユーザー認証のタイムアウト」のための値です。セッションが有効だとしても、時間が経っていた場合に自動ログアウトさせるための設定です。

じゃあなんでsession.gc_maxlifetimeの値を変えているかというと、ドキュメントには次のようにあります。

予期していないふるまいを避けるために、ユーザークラスはセッションガーベッジコレクターの最長有効期間 (session.gc_maxlifetime) をタイムアウトよりも長くなるように強制します。

symfony 1.x legacy website

php.iniのデフォルト値をみるとsession.gc_maxlifetimeは1440秒(=24分)で、symfonyのuserのtimeoutのデフォルトは1800秒(=30分)です。

もしユーザの自動ログアウトまでの時間を3600秒(=1時間)にしたい場合は、.htaccessなどでsession.gc_maxlifetimeを3600(もしくはそれ以上)に設定した上で、factories.ymlを修正してuserのtimeoutを3600にしてあげる必要があります。

ドキュメントとかちゃんと見ないとダメですね。自分でも、こんなこと今更知ったのかよとか思います。。。