NTTドコモ様_dカーシェア
NTTドコモ様_dカーシェア
2014.10.21

AuthComponentで非認証ページと認証ページを共存させる方法

tetsu

こんにちは、管理部兼エンジニアのtetsuです。ひさびさにCakePHPネタを書いてみます。

今回はAuthComponentの使用例として、非認証ページと認証ページを1つの「AppController」でコーディングする例を紹介します。

構成例

CakePHPのプレフィックス機能を利用し、プレフィックス「admin」は認証ページ、プレフィックスが無い場合は非認証ページとします。

//app/config/core.php
Configure::write('Routing.prefixes', array('admin'));

URL上は以下のようになります。

●非認証ページ
  http://exsample.com/コントローラー名/アクション名

●認証ページ
  http://exsample.com/admin/コントローラー名/アクション名

実装例

それでは以下、実装例です。
まずは「AppController」にコンポーネントの設定を以下のように追加します。
※認証するモデルは「User」としています。

class AppController extends Controller {
     public $components = array(
        'Auth' => array(
               'loginAction'=>array(),
               'loginRedirect'=>array(),
               'logoutRedirect'=>array(),
               'authenticate'=>array(
                    'Form' => array(
                         'userModel' => 'User',
                         'fields' => array('username'=>'login_name','password'=>'login_pass'),
                         'scope' => array()
                    )
               ),
               'authorize' => 'Controller'
          ),
     );
}

既にお気づきの方もいると思いますが、ここで重要なポイントがあります。

通常は認証をさせる場合、「loginAction」と「loginRedirect」、「logoutRedirect」を指定しますが、この段階では「array()」とします。

「array()」としているのは、設定してしまうと、非認証ページでも認証するようになってしまうからです。

「それなら、3つとも削除してしまえばいいじゃないか!」と言われそうですが、CakePHPは優しすぎるのか削除してしまうと、自動的に「User」モデルを利用するように設定されてしまいます。
そのため、今回のようなケースの場合は上記のように設定します。

続いてプレフィックス「admin」の認証ページ側のときだけ認証をするようにします。「AppController」に次のコードを追加することで実装が可能となります。

class AppController extends Controller {
     function beforeFilter(){
        if($this->params['prefix']==='admin'){
               //認証ページ側
               $this->Auth->loginAction = array('controller'=>'users','action'=>'login','admin'=>true);
               $this->Auth->loginRedirect = array('controller'=>'users','action'=>'top','admin'=>true);
               $this->Auth->logoutRedirect = array('controller'=>'users','action'=>'login','admin'=>true);
               $this->Auth->allow('');
        }else{
               $this->Auth->allow('*');
        }
    }
}

上記では「beforeFilter」内でプレフィックス「admin」の場合に、最初に指定をしなかった3つの設定「loginAction」と「loginRedirect」、「logoutRedirect」に対して設定をおこない、それ以外は認証をおこなわないように記述します。

以上で今回のケースでの実装例となります。

最終的に「AppController」は以下のような状態となります。

class AppController extends Controller {
     public $components = array(
        'Auth' => array(
               'loginAction'=>array(),
               'loginRedirect'=>array(),
               'logoutRedirect'=>array(),
               'authenticate'=>array(
                    'Form' => array(
                         'userModel' => 'User',
                         'fields' => array('username'=>'login_name','password'=>'login_pass'),
                         'scope' => array()
                    )
               ),
               'authorize' => 'Controller'
          ),
     );

     function beforeFilter(){
        if($this->params['prefix']==='admin'){
               //認証ページ側
               $this->Auth->loginAction = array('controller'=>'users','action'=>'login','admin'=>true);
               $this->Auth->loginRedirect = array('controller'=>'users','action'=>'top','admin'=>true);
               $this->Auth->logoutRedirect = array('controller'=>'users','action'=>'login','admin'=>true);
               $this->Auth->allow('');
        }else{
               $this->Auth->allow('*');
        }
    }
}

ここまでできたら、実際にプレフィックスが無いページと有るページにアクセスしてみましょう。プレフィックス「admin」時のみ認証するようになります。

まとめ

いかがでしたでしょうか。

今回の重要なポイントは

  • コンポーネント設定時に「loginAction」と「loginRedirect」、「logoutRedirect」を「array()」で設定すること

でした。

皆さんの業務にもお役立ていただければと思います。それでは、また。