RSS Feed

 

2010年7月
« 6月    
 1234
567891011
12131415161718
19202122232425
262728293031  

アーカイブ

最近の投稿

カテゴリ

プログラムリンク


Authの罠 ログインできない 前の画面に戻される

2月 2nd, 2010 by nagoling in cakephp

cakephpAuthComponentを使ってみているんですが、これがまた癖が強いです。

変な現象が起きて困ってました。

ログインする→何故か前の画面に戻される
具体的に言うと
/index→users/loginでログインする→/indexに戻される。

どうも原因が分からないのでauth.phpを見てみることに。

まずはredirectメソッドを調べる。

function redirect($url = null) {
if (!is_null($url)) {
  $redir = $url;
  $this->Session->write('Auth.redirect', $redir);
} elseif ($this->Session->check('Auth.redirect')) {
    $redir = $this->Session->read('Auth.redirect');
    $this->Session->delete('Auth.redirect');
  if (Router::normalize($redir) == Router::normalize($this->loginAction)) {
    $redir = $this->loginRedirect;
  }
} else {
  $redir = $this->loginRedirect;
}
  return Router::normalize($redir);
}

二つ目の分岐elseif ($this->Session->check(‘Auth.redirect’))に行っていることが判明。
$redirは/users/indexが入っているかと思いきや、/indexのみ。/indexはログインページ前のページ。
つまりこいつが/users/indexじゃないのが原因というのが分かった。
ということはSessionに入っているAuth.redirectの値を入れているところを検索。
redirect()メソッド以外でAuth.redirectに書き込みをしている箇所は二つ。
startup()メソッドで書き込みが行われているっぽいです。

問題があるのはここ

  if ($loginAction == $url) {
    if (empty($controller->data) || !isset($controller->data[$this->userModel])) {
      if (!$this->Session->check('Auth.redirect') && env('HTTP_REFERER')) {
        $this->Session->write('Auth.redirect', $controller->referer(null, true));
      }
      return false;
    }

Auth.redirectにrefererを突っ込んでいる。
リファラーだから、/users/loginに来る前のページ/indexが入る。
つまり、ログイン後のredirectがおかしくなる。

これは一体何をやっている処理なのか考えてみる。
リファラーを取っているということはセッション切れでログインしたときに、セッションが切れる前のページに戻すための処理だろう。

この機能は必要なものなので引数ミスとかではなさそう。
ということは、ここに来るまでの分岐がおかしい。

3番目の分岐はリファラーの有無とセッションチェックを行っているだけ。
2番目の分岐はid,passが入力前かどうかのチェック
1番目の分岐が何やら怪しい。
$loginActionはデフォルトではnull。今回はコントローラーでloginAction=/users/login と指定している。
$urlは コントローラーの$param['url']['url']から取っている。この$param['url']['url']は何者かというといまアクセスしたコントローラーとアクション名とパラメータが入ってくる。ログインページなら/users/loginとなる。
この二つの変数はRouter::normalize()でnormalizeされた後に比較されている。当然同じ値なのでイコールは成立。

これがおかしいのでは??

解決する方法を二つ思いついた。

一つはloginActionを指定しない。
そうすることで$url$loginActionの分岐は成立しない。

二つ目はログインページの遷移はログインページ(/users/login)そのものを指定しない。/users/indexのように指定しして/users/loginページにリダイレクトさせる。そうすることによってリファラーが/users/indexになるので正常にログインさせることが出来る。

それにしても、ググってもこの話題はほぼないし、Authを使う人たちはこの現象に困らないのだろうか。
何かポカしてるのかな。

Authの参考
http://www.ideaxidea.com/archives/2009/10/cakephp_auth_component.html
if (!is_null($url)) {
  $redir = $url;
  $this->Session->write(‘Auth.redirect’, $redir);
} elseif ($this->Session->check(‘Auth.redirect’)) {
    $redir = $this->Session->read(‘Auth.redirect’);
    $this->Session->delete(‘Auth.redirect’);
  if (Router::normalize($redir) == Router::normalize($this->loginAction)) {
    $redir = $this->loginRedirect;
  }
} else {
  $redir = $this->loginRedirect;
}
  return Router::normalize($redir);
}

二つ目の分岐elseif ($this->Session->check('Auth.redirect'))に行っていることが判明。
$redirは/users/indexが入っているかと思いきや、/indexのみ。/indexはログインページ前のページ。
つまりこいつが/users/indexじゃないのが原因というのが分かった。
ということはSessionに入っているAuth.redirectの値を入れているところを検索。
redirect()メソッド以外でAuth.redirectに書き込みをしている箇所は二つ。
startup()メソッドで書き込みが行われているっぽいです。

問題があるのはここ

  if ($loginAction == $url) {
    if (empty($controller->data) || !isset($controller->data[$this->userModel])) {
      if (!$this->Session->check('Auth.redirect') && env('HTTP_REFERER')) {
        $this->Session->write('Auth.redirect', $controller->referer(null, true));
      }
      return false;
    }

Auth.redirectにrefererを突っ込んでいる。
リファラーだから、/users/loginに来る前のページ/indexが入る。
つまり、ログイン後のredirectがおかしくなる。

これは一体何をやっている処理なのか考えてみる。
リファラーを取っているということはセッション切れでログインしたときに、セッションが切れる前のページに戻すための処理だろう。

この機能は必要なものなので引数ミスとかではなさそう。
ということは、ここに来るまでの分岐がおかしい。

3番目の分岐はリファラーの有無とセッションチェックを行っているだけ。
2番目の分岐はid,passが入力前かどうかのチェック
1番目の分岐が何やら怪しい。
$loginActionはデフォルトではnull。今回はコントローラーでloginAction=/users/login と指定している。
$urlは コントローラーの$param['url']['url']から取っている。この$param['url']['url']は何者かというといまアクセスしたコントローラーとアクション名とパラメータが入ってくる。ログインページなら/users/loginとなる。
この二つの変数はRouter::normalize()でnormalizeされた後に比較されている。当然同じ値なのでイコールは成立。

これがおかしいのでは??

解決する方法を二つ思いついた。

一つはloginActionを指定しない。
そうすることで$url$loginActionの分岐は成立しない。

二つ目はログインページの遷移はログインページ(/users/login)そのものを指定しない。/users/indexのように指定しして/users/loginページにリダイレクトさせる。そうすることによってリファラーが/users/indexになるので正常にログインさせることが出来る。

それにしても、ググってもこの話題はほぼないし、Authを使う人たちはこの現象に困らないのだろうか。
何かポカしてるのかな。

Authの参考
http://www.ideaxidea.com/archives/2009/10/cakephp_auth_component.html

Leave a Reply

Trackback URL

管理者の承認後に表示します。無関係な内容や、リンクだけで意見や感想のないものは承認しません。