シンプルな認証と承認のアプリケーション ? CakePHP Cookbook v2.x documentation
http://book.cakephp.org/2.0/ja/tutorials-and-examples/blog-auth-example/auth.html
を利用して、フォーム認証(普通のユーザー名とパスワードを使ったログイン)を実装する。
というか、チュートリアルのままで動かしてみるというテスト。
- テーブルを作る。
- cake bake して、CRUD を作る。
- ログイン認証部分を作る。
- ロールとユーザーでアクセスを制御する。
の流れになる。
■必要なテーブル
テストするための最低限のテーブルを用意する。
ブログチュートリアル ? CakePHP Cookbook v2.x documentation
http://book.cakephp.org/2.0/ja/tutorials-and-examples/blog/blog.html
□posts テーブル
/* まず、postsテーブルを作成します: */ CREATE TABLE posts ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, title VARCHAR(50), body TEXT, created DATETIME DEFAULT NULL, modified DATETIME DEFAULT NULL ); /* それから、テスト用に記事をいくつか入れておきます: */ INSERT INTO posts (title,body,created) VALUES ('タイトル', 'これは、記事の本文です。', NOW()); INSERT INTO posts (title,body,created) VALUES ('またタイトル', 'そこに本文が続きます。', NOW()); INSERT INTO posts (title,body,created) VALUES ('タイトルの逆襲', 'こりゃ本当にわくわくする!うそ。', NOW());
□users テーブル
CREATE TABLE users ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50), password VARCHAR(50), role VARCHAR(20), created DATETIME DEFAULT NULL, modified DATETIME DEFAULT NULL );
※規約にしたがって、複数形「posts」と「users」で用意すると、$useTable しなくて済む…が、既存のテーブルを使っても可能。
※列名を created, modified としておくと、自動で作成日時、更新日時が入る。手作業でやる場合は別途調査。
■Config/database.php を書き換える
cake bake がデータベースに接続できるように detabase.php を書き換えておく。
class DATABASE_CONFIG { public $default = array( 'datasource' => 'Database/Mysql', 'persistent' => false, 'host' => 'localhost', 'login' => 'user', 'password' => 'password', 'database' => 'test_database_name', 'prefix' => '', 'encoding' => 'utf8', ); }
■cake bake all で MVC を作成する
Consolecake bake all で Post と User の MVC を作成する。
※面倒がなければ、phpunit のひな形も作成しまえばok。
■IE で確認
http://localhost:81/cakeu/Posts
http://localhost:81/cakeu/Users
にアクセスをして確認(フォルダ名とポートは適宜変更)
この状態で、自由に Post と User が編集できる状態になる。
■できあがった MVC
cake bake all すると同じものができるけど、あとから参照できるの自動生成される MVC ファイルを貼り付けておきます。ソースコードを見ると、$this->request->is(‘post’) な REST の部分とか、$this->Session->setFlash なセッション部分とかが生成されていて、御影上ややこしくなっているけど、マスターテーブルの編集なんかはこれで十分なので、そのまま活用してもよいと思う。
□Model/Post.php
<?php App::uses('AppModel', 'Model'); /** * Post Model * */ class Post extends AppModel { } [/code] <p> ※リンクとかしてないので空っぽ </p> <p> □Controller/PostController.php [code lang="php"] <?php App::uses('AppController', 'Controller'); /** * Posts Controller * * @property Post $Post */ class PostsController extends AppController { /** * index method * * @return void */ public function index() { $this->Post->recursive = 0; $this->set('posts', $this->paginate()); } /** * view method * * @throws NotFoundException * @param string $id * @return void */ public function view($id = null) { if (!$this->Post->exists($id)) { throw new NotFoundException(__('Invalid post')); } $options = array('conditions' => array('Post.' . $this->Post->primaryKey => $id)); $this->set('post', $this->Post->find('first', $options)); } /** * add method * * @return void */ public function add() { if ($this->request->is('post')) { $this->Post->create(); if ($this->Post->save($this->request->data)) { $this->Session->setFlash(__('The post has been saved')); $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash(__('The post could not be saved. Please, try again.')); } } $users = $this->Post->User->find('list'); $this->set(compact('users')); } /** * edit method * * @throws NotFoundException * @param string $id * @return void */ public function edit($id = null) { if (!$this->Post->exists($id)) { throw new NotFoundException(__('Invalid post')); } if ($this->request->is('post') || $this->request->is('put')) { if ($this->Post->save($this->request->data)) { $this->Session->setFlash(__('The post has been saved')); $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash(__('The post could not be saved. Please, try again.')); } } else { $options = array('conditions' => array('Post.' . $this->Post->primaryKey => $id)); $this->request->data = $this->Post->find('first', $options); } $users = $this->Post->User->find('list'); $this->set(compact('users')); } /** * delete method * * @throws NotFoundException * @param string $id * @return void */ public function delete($id = null) { $this->Post->id = $id; if (!$this->Post->exists()) { throw new NotFoundException(__('Invalid post')); } $this->request->onlyAllow('post', 'delete'); if ($this->Post->delete()) { $this->Session->setFlash(__('Post deleted')); $this->redirect(array('action' => 'index')); } $this->Session->setFlash(__('Post was not deleted')); $this->redirect(array('action' => 'index')); } }
□Model/User.php
<?php App::uses('AppModel', 'Model'); /** * User Model * */ class User extends AppModel { } [/code] <p> ※Post と同じようにリンクとかしてないので空っぽ </p> ※外部キーを使うと、Post と User がリンクするようになる </p> <p> □Controller/UserController.php [code lang="php"] <?php App::uses('AppController', 'Controller'); /** * Users Controller * * @property User $User */ class UsersController extends AppController { /** * index method * * @return void */ public function index() { $this->User->recursive = 0; $this->set('users', $this->paginate()); } /** * view method * * @throws NotFoundException * @param string $id * @return void */ public function view($id = null) { if (!$this->User->exists($id)) { throw new NotFoundException(__('Invalid user')); } $options = array('conditions' => array('User.' . $this->User->primaryKey => $id)); $this->set('user', $this->User->find('first', $options)); } /** * add method * * @return void */ public function add() { if ($this->request->is('post')) { $this->User->create(); if ($this->User->save($this->request->data)) { $this->Session->setFlash(__('The user has been saved')); $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash(__('The user could not be saved. Please, try again.')); } } } /** * edit method * * @throws NotFoundException * @param string $id * @return void */ public function edit($id = null) { if (!$this->User->exists($id)) { throw new NotFoundException(__('Invalid user')); } if ($this->request->is('post') || $this->request->is('put')) { if ($this->User->save($this->request->data)) { $this->Session->setFlash(__('The user has been saved')); $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash(__('The user could not be saved. Please, try again.')); } } else { $options = array('conditions' => array('User.' . $this->User->primaryKey => $id)); $this->request->data = $this->User->find('first', $options); } } /** * delete method * * @throws NotFoundException * @param string $id * @return void */ public function delete($id = null) { $this->User->id = $id; if (!$this->User->exists()) { throw new NotFoundException(__('Invalid user')); } $this->request->onlyAllow('post', 'delete'); 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')); } }
以下は、View
□View/Posts/index.ctp
<div class="posts index"> <h2><?php echo __('Posts'); ?></h2> <table cellpadding="0" cellspacing="0"> <tr> <th><?php echo $this->Paginator->sort('id'); ?></th> <th><?php echo $this->Paginator->sort('title'); ?></th> <th><?php echo $this->Paginator->sort('body'); ?></th> <th><?php echo $this->Paginator->sort('created'); ?></th> <th><?php echo $this->Paginator->sort('modified'); ?></th> <th class="actions"><?php echo __('Actions'); ?></th> </tr> <?php foreach ($posts as $post): ?> <tr> <td><?php echo h($post['Post']['id']); ?> </td> <td><?php echo h($post['Post']['title']); ?> </td> <td><?php echo h($post['Post']['body']); ?> </td> <td><?php echo h($post['Post']['created']); ?> </td> <td><?php echo h($post['Post']['modified']); ?> </td> <td class="actions"> <?php echo $this->Html->link(__('View'), array('action' => 'view', $post['Post']['id'])); ?> <?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $post['Post']['id'])); ?> <?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $post['Post']['id']), null, __('Are you sure you want to delete # %s?', $post['Post']['id'])); ?> </td> </tr> <?php endforeach; ?> </table> <p> <?php echo $this->Paginator->counter(array( 'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}') )); ?> </p> <div class="paging"> <?php echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled')); echo $this->Paginator->numbers(array('separator' => '')); echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled')); ?> </div> </div> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Html->link(__('New Post'), array('action' => 'add')); ?></li> <li><?php echo $this->Html->link(__('List Users'), array('controller' => 'users', 'action' => 'index')); ?> </li> <li><?php echo $this->Html->link(__('New User'), array('controller' => 'users', 'action' => 'add')); ?> </li> </ul> </div>
□View/Posts/view.ctp
<div class="posts view"> <h2><?php echo __('Post'); ?></h2> <dl> <dt><?php echo __('Id'); ?></dt> <dd> <?php echo h($post['Post']['id']); ?> </dd> <dt><?php echo __('Title'); ?></dt> <dd> <?php echo h($post['Post']['title']); ?> </dd> <dt><?php echo __('Body'); ?></dt> <dd> <?php echo h($post['Post']['body']); ?> </dd> <dt><?php echo __('Created'); ?></dt> <dd> <?php echo h($post['Post']['created']); ?> </dd> <dt><?php echo __('Modified'); ?></dt> <dd> <?php echo h($post['Post']['modified']); ?> </dd> </dl> </div> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Html->link(__('Edit Post'), array('action' => 'edit', $post['Post']['id'])); ?> </li> <li><?php echo $this->Form->postLink(__('Delete Post'), array('action' => 'delete', $post['Post']['id']), null, __('Are you sure you want to delete # %s?', $post['Post']['id'])); ?> </li> <li><?php echo $this->Html->link(__('List Posts'), array('action' => 'index')); ?> </li> <li><?php echo $this->Html->link(__('New Post'), array('action' => 'add')); ?> </li> <li><?php echo $this->Html->link(__('List Users'), array('controller' => 'users', 'action' => 'index')); ?> </li> <li><?php echo $this->Html->link(__('New User'), array('controller' => 'users', 'action' => 'add')); ?> </li> </ul> </div>
□View/Posts/add.ctp
<div class="posts form"> <?php echo $this->Form->create('Post'); ?> <fieldset> <legend><?php echo __('Add Post'); ?></legend> <?php echo $this->Form->input('title'); echo $this->Form->input('body'); ?> </fieldset> <?php echo $this->Form->end(__('Submit')); ?> </div> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Html->link(__('List Posts'), array('action' => 'index')); ?></li> </ul> </div>
□View/Posts/edit.ctp
<div class="posts form"> <?php echo $this->Form->create('Post'); ?> <fieldset> <legend><?php echo __('Edit Post'); ?></legend> <?php echo $this->Form->input('id'); echo $this->Form->input('title'); echo $this->Form->input('body'); ?> </fieldset> <?php echo $this->Form->end(__('Submit')); ?> </div> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $this->Form->value('Post.id')), null, __('Are you sure you want to delete # %s?', $this->Form->value('Post.id'))); ?></li> <li><?php echo $this->Html->link(__('List Posts'), array('action' => 'index')); ?></li> </ul> </div>
□View/Users/index.ctp
<div class="users index"> <h2><?php echo __('Users'); ?></h2> <table cellpadding="0" cellspacing="0"> <tr> <th><?php echo $this->Paginator->sort('id'); ?></th> <th><?php echo $this->Paginator->sort('username'); ?></th> <th><?php echo $this->Paginator->sort('password'); ?></th> <th><?php echo $this->Paginator->sort('role'); ?></th> <th><?php echo $this->Paginator->sort('created'); ?></th> <th><?php echo $this->Paginator->sort('modified'); ?></th> <th class="actions"><?php echo __('Actions'); ?></th> </tr> <?php foreach ($users as $user): ?> <tr> <td><?php echo h($user['User']['id']); ?> </td> <td><?php echo h($user['User']['username']); ?> </td> <td><?php echo h($user['User']['password']); ?> </td> <td><?php echo h($user['User']['role']); ?> </td> <td><?php echo h($user['User']['created']); ?> </td> <td><?php echo h($user['User']['modified']); ?> </td> <td class="actions"> <?php echo $this->Html->link(__('View'), array('action' => 'view', $user['User']['id'])); ?> <?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $user['User']['id'])); ?> <?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $user['User']['id']), null, __('Are you sure you want to delete # %s?', $user['User']['id'])); ?> </td> </tr> <?php endforeach; ?> </table> <p> <?php echo $this->Paginator->counter(array( 'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}') )); ?> </p> <div class="paging"> <?php echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled')); echo $this->Paginator->numbers(array('separator' => '')); echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled')); ?> </div> </div> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Html->link(__('New User'), array('action' => 'add')); ?></li> <li><?php echo $this->Html->link(__('List Posts'), array('controller' => 'posts', 'action' => 'index')); ?> </li> <li><?php echo $this->Html->link(__('New Post'), array('controller' => 'posts', 'action' => 'add')); ?> </li> </ul> </div>
※何回かテストしているので ID が 1 から始まってない。
※パスワードは、そのまま書き込まれている。これは後でハッシュ値にする。
□View/Users/view.ctp
<div class="posts view"> <h2><?php echo __('Post'); ?></h2> <dl> <dt><?php echo __('Id'); ?></dt> <dd> <?php echo h($post['Post']['id']); ?> </dd> <dt><?php echo __('Title'); ?></dt> <dd> <?php echo h($post['Post']['title']); ?> </dd> <dt><?php echo __('Body'); ?></dt> <dd> <?php echo h($post['Post']['body']); ?> </dd> <dt><?php echo __('Created'); ?></dt> <dd> <?php echo h($post['Post']['created']); ?> </dd> <dt><?php echo __('Modified'); ?></dt> <dd> <?php echo h($post['Post']['modified']); ?> </dd> </dl> </div> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Html->link(__('Edit Post'), array('action' => 'edit', $post['Post']['id'])); ?> </li> <li><?php echo $this->Form->postLink(__('Delete Post'), array('action' => 'delete', $post['Post']['id']), null, __('Are you sure you want to delete # %s?', $post['Post']['id'])); ?> </li> <li><?php echo $this->Html->link(__('List Posts'), array('action' => 'index')); ?> </li> <li><?php echo $this->Html->link(__('New Post'), array('action' => 'add')); ?> </li> </ul> </div>
□View/Users/add.ctp
<div class="posts form"> <?php echo $this->Form->create('Post'); ?> <fieldset> <legend><?php echo __('Add Post'); ?></legend> <?php echo $this->Form->input('title'); echo $this->Form->input('body'); ?> </fieldset> <?php echo $this->Form->end(__('Submit')); ?> </div> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Html->link(__('List Posts'), array('action' => 'index')); ?></li> </ul> </div>
□View/Users/edit.ctp
<div class="posts form"> <?php echo $this->Form->create('Post'); ?> <fieldset> <legend><?php echo __('Edit Post'); ?></legend> <?php echo $this->Form->input('id'); echo $this->Form->input('title'); echo $this->Form->input('body'); ?> </fieldset> <?php echo $this->Form->end(__('Submit')); ?> </div> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $this->Form->value('Post.id')), null, __('Are you sure you want to delete # %s?', $this->Form->value('Post.id'))); ?></li> <li><?php echo $this->Html->link(__('List Posts'), array('action' => 'index')); ?></li> </ul> </div>
この状態から、
認証(ログインとログアウト)
http://book.cakephp.org/2.0/ja/tutorials-and-examples/blog-auth-example/auth.html#id3
を追加していく。