[CakePHP] シンプルな認証を実装する(準備)

シンプルな認証と承認のアプリケーション ? CakePHP Cookbook v2.x documentation
http://book.cakephp.org/2.0/ja/tutorials-and-examples/blog-auth-example/auth.html

を利用して、フォーム認証(普通のユーザー名とパスワードを使ったログイン)を実装する。

というか、チュートリアルのままで動かしてみるというテスト。

  1. テーブルを作る。
  2. cake bake して、CRUD を作る。
  3. ログイン認証部分を作る。
  4. ロールとユーザーでアクセスを制御する。

の流れになる。

■必要なテーブル

テストするための最低限のテーブルを用意する。

ブログチュートリアル ? CakePHP Cookbook v2.x documentation
http://book.cakephp.org/2.0/ja/tutorials-and-examples/blog/blog.html

□posts テーブル

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* まず、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 テーブル

1
2
3
4
5
6
7
8
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 を書き換えておく。

1
2
3
4
5
6
7
8
9
10
11
12
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
App::uses('AppModel', 'Model');
/**
 * Post Model
 *
 */
class Post extends AppModel {
 
}
&#91;/code&#93;
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
App::uses('AppModel', 'Model');
/**
 * User Model
 *
 */
class User extends AppModel {
 
}
&#91;/code&#93;
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<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&#91;'Post'&#93;&#91;'id'&#93;); ?>&nbsp;</td>
        <td><?php echo h($post&#91;'Post'&#93;&#91;'title'&#93;); ?>&nbsp;</td>
        <td><?php echo h($post&#91;'Post'&#93;&#91;'body'&#93;); ?>&nbsp;</td>
        <td><?php echo h($post&#91;'Post'&#93;&#91;'created'&#93;); ?>&nbsp;</td>
        <td><?php echo h($post&#91;'Post'&#93;&#91;'modified'&#93;); ?>&nbsp;</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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<div class="posts view">
<h2><?php  echo __('Post'); ?></h2>
    <dl>
        <dt><?php echo __('Id'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'id'&#93;); ?>
            &nbsp;
        </dd>
        <dt><?php echo __('Title'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'title'&#93;); ?>
            &nbsp;
        </dd>
        <dt><?php echo __('Body'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'body'&#93;); ?>
            &nbsp;
        </dd>
        <dt><?php echo __('Created'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'created'&#93;); ?>
            &nbsp;
        </dd>
        <dt><?php echo __('Modified'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'modified'&#93;); ?>
            &nbsp;
        </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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<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&#91;'User'&#93;&#91;'id'&#93;); ?>&nbsp;</td>
        <td><?php echo h($user&#91;'User'&#93;&#91;'username'&#93;); ?>&nbsp;</td>
        <td><?php echo h($user&#91;'User'&#93;&#91;'password'&#93;); ?>&nbsp;</td>
        <td><?php echo h($user&#91;'User'&#93;&#91;'role'&#93;); ?>&nbsp;</td>
        <td><?php echo h($user&#91;'User'&#93;&#91;'created'&#93;); ?>&nbsp;</td>
        <td><?php echo h($user&#91;'User'&#93;&#91;'modified'&#93;); ?>&nbsp;</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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<div class="posts view">
<h2><?php  echo __('Post'); ?></h2>
    <dl>
        <dt><?php echo __('Id'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'id'&#93;); ?>
            &nbsp;
        </dd>
        <dt><?php echo __('Title'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'title'&#93;); ?>
            &nbsp;
        </dd>
        <dt><?php echo __('Body'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'body'&#93;); ?>
            &nbsp;
        </dd>
        <dt><?php echo __('Created'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'created'&#93;); ?>
            &nbsp;
        </dd>
        <dt><?php echo __('Modified'); ?></dt>
        <dd>
            <?php echo h($post&#91;'Post'&#93;&#91;'modified'&#93;); ?>
            &nbsp;
        </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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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

を追加していく。

カテゴリー: CakePHP パーマリンク