-   topic   - トピックス

[baserCMS4]プレフィックス認証を使わずにログイン機能を実装する

2018年06月26日 技術関係

baserCMSでプレフィックス認証を使わずに、プラグイン側からBcAuthComponent(CakePHPのAuthComponentを拡張したもの)を使ってログイン機能を実装するための実験メモを記載します。

スクリーンショット 2018-06-26 22.56.52.png

この記事の動作環境

  • baserCMSバージョン: 4.1.1(SQLite)
  • CakePHPバージョン: 2.10.6
  • PHP: 5.6.32
  • サーバー: ローカルのMAMP環境

参考記事:
シンプルな認証と承認のアプリケーション
認証

モデルとコントローラーを用意する

今回、認証機能を持たせたいコントローラーを「LoginTesterController」、モデルを「LoginTester」(すなわちTBLは「login_testers」)とします。 認証に使うTBL「login_testers」には、ログインアカウント用のフィールド「username」と、パスワード用のフィールド「password」とを用意します。

コントローラーの設定

プラグイン内で認証機能を持たせたいコントローラーに対して、以下のようにbeforeFilterで認証のための設定を行います。

        
/**
* beforeFilter
*
* @return	void
* @access public
*/
public function beforeFilter() {
    parent::beforeFilter();
    /* 認証設定 */
    // セッションキーの変更(通常の管理画面と分けたい)
    $this->BcAuth->setSessionKey("baserCMS.logintester");
    //BcAuthの認証設定
    $this->BcAuth->authenticate = array(
        'Form' => array(
            'userModel' => 'LoginTester',
            'passwordHasher' => array(
                'className' => 'Simple',
                'hashType' => 'sha256'
            )
        )
    );
    // ログインページ
    $this->BcAuth->loginAction = "/login_tester/login_testers/login";
    // ログイン後リダイレクト先
    $this->BcAuth->loginRedirect = "/login_tester/login_testers/mypage";
    // ログアウト後リダイレクト先
    $this->BcAuth->logoutRedirect = "/login_tester/login_testers/login";
    // 認証エラーメッセージ
    $this->BcAuth->authError = "メンバー登録が必要なページにアクセスしようとしています。";
    //許可するページ
    $this->BcAuth->allow('add', 'login');
    }
        
    

基本的にはCakePHP 2.x Cookbookの通りですが、 今回はbaserCMSがもともと持っている管理画面へのログインユーザーとは分けて認証させたいので、セッションキーを手動で分けてあります。 また、過去のCakePHPでは自動でハッシュ化していたパスワード文字列ですが、現在のバージョンでは無くなっているとのことで「passwordHasher」を使ってハッシュタイプを明示しています。

あとはログイン画面(login)、ログイン後の画面(mypage)などを指定します。認証せずに表示を許可するページとして、新規登録画面(add)とログイン画面(login)を指定しています。 なお、各ページのアクションは以下のように作りました。

            
/**
* 登録処理
*
* @return void
*/
public function add()
{
    //新規会員登録
    if (!empty($this->request->data)) {
        //ユーザー追加
        if ($this->LoginTester->save($this->request->data)) {
            $this->setMessage('登録が完了しました。', false, true);
            $this->redirect(array('action' => 'add'));
        }else {
            $this->setMessage('入力エラーです。内容を修正してください。', true);
        }
    }
}


/**
* ログイン画面
*
* @return void
*/
public function login()
{
    if(!empty($this->request->data)){
        //ログイン実行
        if($this->BcAuth->login($this->request->data)){
            $this->setMessage('ログインしました。', true);
            $this->redirect(array('action' => 'mypage'));
        } else {
            $this->setMessage('ログインに失敗しました。', true);
        }
    }
}


/**
* マイページ(ログイン後の画面)
*
* @return void
*/
public function mypage()
{
    //ログイン中のユーザー名を取得する
    $username = $this->BcAuth->user('LoginTester.username');
    $this->set('username', $username);
}


/**
* ログアウト
*
* @return void
*/
public function logout()
{
    $this->redirect($this->BcAuth->logout());
}
            
        

モデルの設定

続いてモデルを設定していきます。前述の通り、パスワードが自動でハッシュ化されなくなったことに伴う処理を追記していきます。

        
        App::uses('SimplePasswordHasher', 'Controller/Component/Auth');
        
    

まず冒頭に上の一文を記載して、このモデル内でハッシュ化のための処理が使えるように呼び出しておきます。続いてモデルクラス内に以下の処理を追記します。beforeSaveを使って、passwordが保存される際にハッシュ化するようにしています。 ちなみにここで指定されるハッシュタイプと、前項のコントローラーで指定したハッシュタイプは同一である必要があります。

        
/**
* beforeSave
*
* @params array
* @return boolean
*/
public function beforeSave($options = array()) {
    //セーブ時にpasswordフィールドが存在していればハッシュ化する。
    if (!empty($this->data[$this->alias]['password'])) {
        $passwordHasher = new SimplePasswordHasher(array('hashType' => 'sha256'));
        $this->data[$this->alias]['password'] = $passwordHasher->hash(
            $this->data[$this->alias]['password']
        );
    }
    return true;
}
    

ビューの作成

コントローラーとモデルができたらビューを用意します。各ページのアクションはすでに用意したので、そこに対応するビューを作ります。

1. add.php

        
<?php echo $this->BcForm->create('LoginTester'); ?>
<div>
    username:
    <?php echo $this->BcForm->text('LoginTester.username'); ?>
</div>
<div>
    password:
    <?php echo $this->BcForm->password('LoginTester.password'); ?>
</div>
<div>
    email:
    <?php echo $this->BcForm->text('LoginTester.email'); ?>
</div>
<?php echo $this->BcForm->end('add'); ?>
    

2. login.php

        
<?php echo $this->BcForm->create('LoginTester'); ?>
<div>
    username:
    <?php echo $this->BcForm->text('LoginTester.username'); ?>
</div>
<div>
    password:
    <?php echo $this->BcForm->password('LoginTester.password'); ?>
</div>
<?php echo $this->BcForm->end('login'); ?>
        
    

3. mypage.php

        
ようこそ<?php echo $username ?>さん、ここはマイページです。
<?php $this->BcBaser->link('logout', 'logout') ?>
        
    

ログアウト時については、すぐにログイン画面にリダイレクトされるのでビューは必要ありません。

おわりに

baserCMSのプレフィックス認証を使わずにログイン機能を持たせたい場面があれば、このような処理が使えるかも知れません。皆様の参考になれば幸いです。