【CakePHP】DarkAuthComponentを改造してSuperDarkAuthComponentに!

【ご注意!】
本記事は、前記事「【CakePHP】DarkAuthComponentを使ってみる」の続編です。前記事をお読みでない方は、まずこちらをお読みください。

さて、前記事で「DarkAuthComponent」の実装方法などを書いてみたりしたのですが、当方の求めていた仕様の半分を満たしていませんでした。その仕様は「例えばゲストユーザのような、未ログインのユーザでもとりあえず使えるページや、VIPユーザのような特別なユーザのみがアクセスできるページが持てる」というものだったのですが、DarkAuthでは前半部分の、「ゲストユーザがアクセスできない」のです。

それに加え、DarkAuthはコントローラ単位で認証処理が出来ますが、アクション単位では出来ないというのも難点です。例えばusers/indexは認証済みでないと表示できないが、loginやjoinはゲストでもアクセスできる、といった具合の場合分けは是非ともしたいところです。

そこで、この2点を実現でき、しかも「簡単に」実装できる方法を考えてみました。

dark_auth.phpに注目してみますと、実際にアクセスの可否を調べている場所は「requiresAuth()」関数です。そこで、ここの初っぱなにチェックするルーチンを入れ、ゲストユーザだった場合の場合分けを行ってみます。
また、action毎のパーミッションについては、$_DarkAuth['required']['(action名)']のような指定方法にして(つまり配列を一段増やして)、さらにワイルドカード(もどき)の処理も入れることにします。つまり、アクション名に'*'を入れると、全てのアクションが対象になり、グループ名に'*'を入れると、全てのグループに対して処理を行う、といった動作になります。

dark_auth.phpは、次のように改造します(抜粋)。

app/controllers/components/super_dark_auth.php

class SuperDarkAuthComponent extends Object {

    //(省略)

    var $superuser_group = 'Root';  //これは既にある
   
    var $undefined_group = 'NoGroup';  //←これを追加

    //(省略)

    function requiresAuth($action_groups=array(),$deny_redirect=null){
       
        $action = $this->controller->action;
        if(!empty($action_groups)){
            if(isset($action_groups[$action])){
                $groups = $action_groups[$action];
            }else
            if(isset($action_groups['*'])){
                $groups = $action_groups['*'];
            }else{
                $groups = array();
            }
        }else{
            $groups = array();
        }
        if(array_search('*', $groups) !== false){    //2008-10-15修正
            return true;
        }
       
        //↑↑↑修正はここまで↑↑↑

        if(empty($this->current_user)){
            if(array_search($this->undefined_group, $groups) !== false){
                return true;
            }else
           
            // Still no info! render login page!
            if($this->from_post){
                $this->Session->setFlash($this->login_failed_message);
            }
            echo $this->controller->render($this->login_view);
            exit();
        }else{
            if($this->from_post){
                // user just authed, so redirect to avoid post data refresh.
                $this->controller->redirect($this->here,null,null,true);
                exit();
            }
            // User is authenticated, so we just need to check against the groups.
            if( empty($groups) ){
                // No Groups specified so we are good to go!
                $deny = false;
            }else{
                $deny = !$this->isAllowed($groups);
            }
            if($deny){
                // Current User Doesn't Have Access! DENY
                if($deny_redirect){
                    $this->controller->redirect($deny_redirect);
                    exit();
                }else{
                    echo $this->controller->render($this->deny_view);
                    exit();
                }
            }
        }
        return true;
    }

    //(省略)
}

修正箇所はたったこれだけです。
同じコンポーネント名でも良いのですが、同じだと紛らわしいので、仮に「SuperDarkComponent」としましょう(笑)。

次に、コントローラ内の$_DarkAuth配列を修正します。
例えば次のように指定します。

app/controller/users_controller.php

    var $_DarkAuth = array(
        'required' => array(
            'index' => array(
                'Huga',
            ),
            'edit' => array(
                'Huga',
            ),
            'join' => array(
                'NoGroup',
            ),
            '*' => array(
                '*',
            ),
        ),
        'onDeny' => '/',
    );

上の例では、indexとeditはHugaグループのみ、joinはゲストのみ、それ以外は誰でもアクセスが出来ます。

ちなみに、コンポーネント名をDarkAuthからSuperDarkAuthに変更したので、users_controller.php内のコンポーネント名は全て変更してください。でないと動きません。その他の場所については今回触っていないため、全てDarkAuthの名称になっていると思います。
また、「NoGroup」の名称はbeforeFilter()内で変更することが出来ます。グループ名でこの名前を使いたい場合は変更します。逆に、NoGroupというグループはgroupsテーブル内に存在しないようにしてください。

上記改造後に実行してみると、おおよそそのように動くのが確認できるかと思います。

全ての機能については検証していないので分からないのですが、とりあえず必要条件は満たせそうです。当方のサイトも、これをベースに作っていきたいと思います。


“【CakePHP】DarkAuthComponentを改造してSuperDarkAuthComponentに!” への2件の返信

  1. I need to contact site admin urgently. Can you understand me?
    Hope for no silence

コメントは受け付けていません。