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 ;
フィールド名 | 型 | 説明 |
id | int | 必須 Authに必須 auto-increment |
username | varchar | 必須 Authに必須 e-mailアドレス |
password | varchar | 必須 Authに必須 |
role | varchar | (オプション)admin, manager, userの役割で分ける |
status | int | (オプション)登録ステータス |
name | varchar | (オプション)氏名は漢字で欲しい |
created | datetime | (オプション)登録日時 |
modified | datetime | (オプション)変更日時 |
(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の人は、消去できるのは、自分のアカウントだけとか、消去できない、など、自己の仕様により、書き直してください。