Cookieなし、URL埋め込み型セッションIDを使っているときに、returnUrlが設定されずに、ログイン後にindex.phpに飛ばされてしまいます。
これでは不便なのでちょっと調べてみることにしました。
通常はreturnUrlはセッションに「セッションID__returnRul」の変数で保存されていますが、cookieオフの設定では$_SESSIONの中身を読み出しても設定されていませんでした。
Webで探しても自分で設定しなさいとか、よくわかんないや、バグじゃね?みたいな情報しか見つけられなかったので、CWebUser.phpを読んでいくことに。
ReturnUrlプロパティが設定されるまで
CAccessControlFilter.php
accessDeniedメソッドからCWebUser.phpのloginRequireメソッドを呼び出し。
CWebUser.php
loginRequired→setReturnUrlメソッド→setStateメソッド。ここでセッションID_returnUrlを設定している。
Cookie関係なくセットはされているようだけど、ログインページに飛ばす際にセッションIDなしでredirectされているのが原因のようです。
原因は
認証が必要なページにアクセスしたときに振られたセッションIDにはreturnUrlが含まれていますが、リダイレクト後はセッションIDが含まれないURL(/site/login)のため、$_SESSIONにも値が入っていないというのが原因でした。
対策方法
CWebUser.phpのloginRequiredメソッドの$this->redirect()部分にセッションIDを含める方法と、requestオブジェクトのredirectを書き換える方法があります。
ほかの部分でもredirect時にセッションIDが含まれていないということがおこるので、問題の根っこ部分$this->redirect自体をオーバーライドすることにします。
まずは/protected/HttpRequest.phpを作成、CHttpRequestを継承してredirect部分だけオーバーライドします。
/protected/components/HttpRequest.php
class HttpRequest extends CHttpRequest { public function redirect($url, $terminate=true, $statusCode=302) { if (strpos($url, '/') === 0) { if (strpos($url, '?') !== false) { $url = $this->getHostInfo() . $url; } else { $url = $this->getHostInfo() . $url . (SID ? ('?' . htmlspecialchars(SID, ENT_QUOTES, Yii::app()->charset)) : ''); } } header('Location: ' . $url, true, $statusCode); if ($terminate) Yii::app()->end(); } }
つぎに設定ファイルでrequestオブジェクトにHttpRequestクラスを使うように指定します。
/protected/config/main.php
‘components’ => array(
‘request’ => array(
‘class’ => ‘HttpRequest’,
‘enableCsrfValidation’ => true,
),
これでreturnUrlが設定されるようになった。