Ethnaでモバイル セッション

前回の記事の続きです。

前回の設定でとりあえずは問題なさそうだったのだが、今日チェックしているとDoCoMoで問題が起きた。

DoCoMoでだけ、セッションが引き継がれない。

URLにセッションIDが引き継がれてないのかな?と思ったが、正常に引き継がれている。

少し悩んである事を思い出した。

Ethnaでセッション使うと記録される内容にIPアドレスが含まれてたな〜。

って事で、Ethna_Sessionを調べてみた。

Ethna_Sessionはリクエスト毎に、自動的に呼び出されて、CookieやURLにセッションIDがあれば自動でセッションを開始(Ethna_Session::restore)してくれる。

restoreの中身を見ていると以下の部分が気になった。

<?php
// check session
if ($this->isValid() == false) {
    setcookie($this->session_name, "", 0, "/");
    $this->session_start = false;
}
?>

isValidが通らなかったらセッションを消去してるぽい。

isValidでは不正なセッションだった場合、強制的にdestroyしてる。

で、その不正なセッションの判定の一部にセッションハイジャック対策のためか、
保持しているIPアドレスと接続元のIPアドレスが同じでなかった場合、不正とみなしている。


まさにこれが原因ぽい。

DoCoMoの場合、リクエスト毎にゲートウェイが変わるのでIPは毎回変わる。

恐らくこれだろうって事で、対策。

対策としては、まぁPCの場合はURLベースでやることはないだろうってことで

session.use_only_cookiesがtrueの時だけ、_validateRemoteAddrを実行するように変更。

先日の日記で作ったクラスにisValidメソッドを追加。

<?php
    /**
     *  セッションの正当性チェック
     *
     *  @access public
     *  @return bool    true:正当なセッション false:不当なセッション
     */
    function &isValid()
    {
        if (!$this->session_start) {
            if (!empty($_COOKIE[$this->session_name]) || session_id() != null) {
                setcookie($this->session_name, "", 0, "/");
            }
            return false;
        }
        
        // Cookieが有効時のみチェック (FOMA対策)
        if (ini_get('session.use_only_cookies')) {
            // check remote address
            if (!isset($_SESSION['REMOTE_ADDR'])
                || $this->_validateRemoteAddr($_SESSION['REMOTE_ADDR'],
                                              $_SERVER['REMOTE_ADDR']) == false) {
                // we do not allow this
                setcookie($this->session_name, "", 0, "/");
                session_destroy();
                $this->session_start = false;
                return false;
            }
        }
        
        return true;
    }
?>

DoCoMoで確認してみると、ちゃんと通った。

問題なさそうだね。