2012年9月5日水曜日

cakephp2.2 Auth認証 と usersテーブル、その1

Auth認証 と usersテーブル と モデル/コントローラ/ビュー

cakephpの認証機能は、とてもわかりやすいので、いいですね。
usersテーブルは、ログインしたユーザのデータを格納する大切なテーブルですね。

usersテーブルとM/C/Vを作成しながら、Auth(認証の設定)を進めます。

Sessionをdatabaseで管理する設定はこちら
(1)cake_sessionsテーブルが作成済みである
(2)core.phpで、Sessionをdatabaseで行う設定済みである。
(上記、2つなくても、Authは動きます)

作業手順
1)Sessionはデータベースで管理
  1.core.php に databaseで管理する設定をする 
  2.cake_sessionsテーブルを作成
2)usersテーブルを作成する
  1.userテーブルを作成
  2.roleを検討
3)bakeで UserモデルとUsersコントローラ、ビューを作成する
4)Usersコントローラの修正
5)indexファンクションとindex.ctp(ビュー)の修正
6)editファンクションとedit.ctp(ビュー)の修正
7)addファンクションとadd.ctp(ビュー)の修正
(1)usersテーブルの作成
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(128) NOT NULL,
  `password` varchar(255) NOT NULL,
  `role` varchar(20) DEFAULT NULL,
  `status` int(11) DEFAULT '0',
  `name` varchar(24) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

フィールド名説明
idint必須 Authに必須 auto-increment
usernamevarchar必須 Authに必須 e-mailアドレス
passwordvarchar必須 Authに必須
rolevarchar(オプション)admin, manager, userの役割で分ける
statusint(オプション)登録ステータス
namevarchar(オプション)氏名は漢字で欲しい
createddatetime(オプション)登録日時
modifieddatetime(オプション)変更日時

(1-1)スキーマファイルを作る。 bakeする(モデル、コントローラ、ビューを焼く)
(1)パスを通す
【windowsの場合】
webapp/app/Config/Console に 移動して

>set path=%path%;%cd%  (パスを Consoleに通し、bakeコマンドを使えるようにする)

webapp/app/に移動する

(2)スキーマファイルを作る
【windowsの場合】

>cake schema generate -f (次のメッセージでは、上書きの(o)を選択し、schemaファイルを作っておく

(3)bakeする

>cake bake で、 Model と Controller と View を 作ってください。

(1-2)認証とセッションは、どこでも使うので、AppControllerに登録しておきます。
class AppController extends Controller {
 var $components = array('Session','Auth');
 var $helpers=array('Session');
}

(2)Userモデル bakeしたままで、OKです

(3-1)Usersコントローラ (上の部分)
<?php
App::uses('AppController', 'Controller');

class UsersController extends AppController {
    var $layout = 'demo';
    public $uses = array('User', 'Auth', 'Session');
    public $components = Array(
            'Session',
            'Auth' => Array(
                'loginRedirect' => Array('controller'  => 'mypages', 'action' => 'index'),
                'logoutRedirect' => Array('controller' => 'users', 'action' => 'login'),
                'loginAction' => Array('controller' => 'users', 'action' => 'login')
 /*             'authenticate' => Array('Form' => Array('fields' => Array('username' => 'email')))  */
            )
        );


    public function beforeFilter() {

    parent::beforeFilter();
    $this->Auth->allow('login', 'logout', 'signup', 'add');

    $this->Auth->authError = 'ログインしてください';
    $this->Auth->loginError = 'メールアドレスかパスワードが違います';
  } 
(解説)
$layout    このコントローラ内のレイアウトを'demo'に設定。違うレイアウトを使う場合は、それそれの
       function内で再度、定義すればよい。
$uses     利用するモデルを列挙する。
$components     利用するコンポーネントを列挙する


(3-2)Usersコントローラ (login)
 function login() {
 $this->set('title_for_layout','ログイン');

        if($this->request->is('post')) {
            if($this->Auth->login()) {
             $loginuser = $this->Auth->user();
             $this->Session->write('LoginUser.Id', $loginuser['id']);
             $this->Session->write('LoginUser.UserName', $loginuser['username']);
             $this->Session->write('LoginUser.Name', $loginuser['name']);
             $this->Session->write('LoginUser.Role', $loginuser['role']);
             if ($loginuser['role'] == 'admin')  {
              $this->redirect(array('controller' => 'menus', 'action' => 'index'));
             } else {
              $this->redirect(array('controller' => 'favorites', 'action' => 'index'));
                }
            } else {
                $this->Session->setFlash(__('ユーザ名かパスワードが違います'));
            }
        }
    }
解説
・リクエストが、'post'じゃなかったら、そのまま、抜ける。
・リクエストが、'post'で、logoin認証がOKの時に
    Loginユーザのroleが 'admin'だったら、管理のページへリダイレクトして、
    Loginユーザのroleが 'その他’だったら、ユーザのページへリダイレクトする。
・リダイレクトの前に、セッションに、Loginユーザの情報を書き込んでおく。
(3-3)Usersコントローラ (logout)
 function logout() {
  $this->Session->write('LoginUser.Id', '');
  $this->Session->write('LoginUser.UserName', '');
  $this->Session->write('LoginUser.Name', '');
  $this->Session->write('LoginUser.Role', '');
  $this->redirect($this->Auth->logout());
 }

・セッション情報をクリアして、logoutする

(3-4)Usersコントローラ (index)
 function index() {
  $this->set('title_for_layout','ユーザ一覧');

  $this->User->recursive = 0;
  $this->set('users', $this->paginate());

  $allusers = new User;
  $allusers = $this->User->find('all',array(
   'conditions' => array('role <>' => 'admin'),
   'order' => array('User.id' => 'asc')
   ));
  $this->set('allusers', $allusers);
 }

・ロール(役割)がadminを表示したくない場合は、上記の$alluserのようなオブジェクトを作る

(3-5)Usersコントローラ (edit)
 public function edit($id = null) {
  $this->User->id = $id;
  if (!$this->User->exists()) {
   throw new NotFoundException(__('Invalid user'));
  }
  if ($this->request->is('post') || $this->request->is('put')) {
  $this->request->data['User']['password'] = AuthComponent::password($this->request->data['User']['password']);
   if ($this->User->save($this->request->data)) {
    $this->Session->setFlash(__('The user has been saved'));
    if($this->Session->read('LoginUser.Role' == 'admin')){
    $this->redirect(array('action' => 'edit'));
    } else if ($this->Session->read('LoginUser.Role' == 'user')){
     $this->redirect(array('action' =>'view'));
    }
   } else {
    $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
   }
  } else {
   if($this->Session->read('LoginUser.Role') == 'user'){
    $id = $this->Session->read('LoginUser.Id');
    }
   $this->request->data = $this->User->read(null, $id);
  }
 }

・処理をロールがadmi userなどで分けたい場合は、上記のような処理をする
・自分の仕様に従って書き直してください

(3-6)Usersコントローラ (add)
 public function add() {
  $this->set('title_for_layout','ユーザ:新規登録');

  if ($this->request->is('post')) {
   $this->User->create();
   $this->request->data['User']['password'] = AuthComponent::password($this->request->data['User']['password']);
   if ($this->User->save($this->request->data)) {
    $this->Session->setFlash(__('次:ユーザ情報の登録・ログインしてください'));
    $this->redirect(array('controller' => 'users', 'action' => 'add'));
   } else {
    $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
   }
  }

  $this->User->recursive = 0;
  $this->set('users', $this->paginate());

  $allusers = new User;
  $allusers = $this->User->find('all',array(
   'conditions' => array('role <>' => 'admin'),
   'order' => array('User.id' => 'asc')
   ));
  $this->set('allusers', $allusers);
 }

・パスワードの暗号化:$this->request->data['User']['password'] = AuthComponent::password($this->request->data['User']['password']); の部分が大事
・ユーザ新規登録は、「signUpファンクションを作る」など、自己のプログラムの仕様に従って、書き直してください。

(3-7)Usersコントローラ (view)
 public function view($id = null) {

  $this->User->id = $id;
  if (!$this->User->exists()) {
   throw new NotFoundException(__('Invalid user'));
  }
  $this->set('user', $this->User->read(null, $id));
 }

・ロールがuserの人は、自分のアカウントしか見られない、など、自己の仕様に従って、書き直してください。

(3-8)Usersコントローラ (delete)
 public function delete($id = null) {
  if (!$this->request->is('post')) {
   throw new MethodNotAllowedException();
  }
  $this->User->id = $id;
  if (!$this->User->exists()) {
   throw new NotFoundException(__('Invalid user'));
  }
  if ($this->User->delete()) {
   $this->Session->setFlash(__('User deleted'));
   $this->redirect(array('action' => 'index'));
  }
  $this->Session->setFlash(__('User was not deleted'));
  $this->redirect(array('action' => 'index'));
 }

・ロールがuserの人は、消去できるのは、自分のアカウントだけとか、消去できない、など、自己の仕様により、書き直してください。


0 件のコメント:

コメントを投稿