CakePHPでサイドバーにログインボックスを作る方法

ログインコンテナって?

というわけでこの前からちょいこちょことサイトを作成しながらcakePHPを勉強しています。
今日はすべての画面に表示されているサイドバーにログインコンテナを作る方法についてcakePHPの知識不足もあって手間取ってしまったのでまとめ直して置きます。
上で言っているログインボックスがどういうものかというと下の画像のようなもので、サイドバーとログインコンテナはサイトの全ての画面に表示されることが条件です。

  • ログイン前:ログイン情報を入力するフォームを表示

  • ログイン後:ユーザの登録情報とログアウトボタンを表示



作成の流れ

  1. ログインボックスの~/app/views/elements/にテンプレートを作成(ログイン前と後の2種類)
  2. ~/app/controllers/users_controller.phpに実際の処理を行い上のテンプレートを描画する関数を書く
  3. ログインボックスを表示したい所(例では~/app/views/layouts/default.thtml)の中に上の関数をrequestActionする部分を加える


準備

次のような環境で作成しています

  • 以下のようなユーザのテーブルを作成
CREATE TABLE `users` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(255) NOT NULL,
  `password` varchar(32) NOT NULL,
  `mailaddress` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
)
  • app/models/user.phpを作成
<?php
class User extends AppModel{
    var $name = 'User';
    function checkSession($sessionData){
  //この関数の中にセッションの有効性をチェックするような関数を書いてください
    }             
}
?>
  • app/controllers/users_controller.phpを作成
<?php
class UsersController extends AppController
{
}
?>

コード

1.ログインボックスのテンプレートを作成
/app/views/elements/loginbox.thtml
  • ログイン前のボックスのテンプレート
<div id="sidecontent">
<?if ($error): ?>
<p>入力されたログイン情報を確認できませんでした。もういちど入力してください。</p>
<? endif; ?>
<h2>User</h2>
<form action="<?php echo $html->url('/'); ?>" method="post">
<div>
    <label for="username">ユーザ名:</label>
    <?php echo $html->input('User/username', array('size' => 20)); ?>
</div>
<div>
    <label for="password">パスワード:</label>
    <?php echo $html->password('User/password', array('size' => 20)); ?>
</div>
<div>
    <?php echo $html->submit('ログイン'); ?>
</div>
</form>
</div>
/app/views/elements/userinfobox.thtml
  • ログイン後のボックスのテンプレート
  • $userにはセッションからの情報を格納する
<div id="sidecontent">
<h2>User</h2>
<p>name:<?php echo $user["username"] ?></p>
<p><?php echo $html->link("logout","/users/logout") ?></p>
</div>
2.コントローラの作成
app/controllers/users_controller.php
  • sideboxlogin()関数を追加します
  • セッションの有効性をチェックするために独自に作ったcheckSession関数を利用していることに注意してください
  • ここの部分は自分でセッションチェック関数を適当に作成してください。
  • 10/9追記 ログインフォーム以外のフォームからデータがPOSTされた時、Noticeが出ていたので修正しました。
<?php
    function sideboxlogin() {
        $this->set('error', false);
        $someone = $this->User->findByUsername($this->data['User']['username']);
        if( $this->User->checkSession($this->Session->read('User')) ){
            //modelにcheckSession関数を作ってそこでセッションの有効性をチェックしている
            $this->set('user',$this->Session->read('User'));
            $this->render('../elements/userinfobox');
            //セッションが入っている場合はメニュー表示
        }else{
            if(!empty($this->data['User'])){
                       if( !empty($someone['User']['password']) && $someone['User']['password']
                                                          == $this->data['User']['password'] ){       
                       //普通はパスワードを暗号化してると思うので
                       //仕様に合わせて上の一致条件は書き換えてください
                        $this->Session->write('User', $someone['User']);
                        $this->set('user',$this->Session->read('User'));
                        $this->render('../elements/userinfobox');
                        //データを受け取って、DBと一致すればログイン処理
                    }else{
                        $this->set('error',true);
                        $this->render('../elements/loginbox');
                        //DBと一致しなければエラーフラグ
                    }
            }else{                
                $this->render('../elements/loginbox');
                //データを受け取ってないときはログインボックス表示
            } 
        } 
    } 
?>
3.layouts/default.thtmlに上のコントローラをset
app/views/layouts/default.thtml
  • ログインボックスを設置させたい箇所に以下のように記述
<?php echo $this->requestAction('/users/sideboxlogin', array('return')); ?>

これで

表示できたでしょうか?
今回CakePHPにまだまだ慣れてないので効率の悪い点,セキュリティ上問題のある点、動作がおかしい点など
気がついた方はお気軽に報告していただけるとうれしいです。