CakePHP UserAuthentication
rrd
This book is for sale athttp://leanpub.com/CakePHPUserAuthentication
This version was published on 2014-12-20
This is a Leanpub book. Leanpub empowers authors andpublishers with the Lean Publishing process. LeanPublishing is the act of publishing an in-progress ebookusing lightweight tools and many iterations to get readerfeedback, pivot until you have the right book and buildtraction once you do.
©2013 - 2014 rrd
Tweet This Book!Please help rrd by spreading the word about this book onTwitter!
The suggested tweet for this book is:
I just bought CakePHP User Authentication e-book.#CakePHPhttps://leanpub.com/CakePHPUserAuthentication
The suggested hashtag for this book is #cakephp.
Find out what other people are saying about the book byclicking on this link to search for this hashtag on Twitter:
https://twitter.com/search?q=#cakephp
Contents
Introduction . . . . . . . . . . . . . . . . . . . . . i
About the Book . . . . . . . . . . . . . . . . . . . iiWhy I Wrote This Book . . . . . . . . . . . . . iiMy Development Environment . . . . . . . . . ivWho This Book Is For . . . . . . . . . . . . . . . ivPrerequisites . . . . . . . . . . . . . . . . . . . . iv
About the Author . . . . . . . . . . . . . . . . . . v
Thanks . . . . . . . . . . . . . . . . . . . . . . . . vi
My E-books on CakePHP . . . . . . . . . . . . . . viiCakePHP Unit Testing . . . . . . . . . . . . . . viiCakePHP User Authentication . . . . . . . . . . viii
My CakePHP Plugins . . . . . . . . . . . . . . . . ix
Model Preparation . . . . . . . . . . . . . . . . . . 1Creating User Table . . . . . . . . . . . . . . . . 1Baking User . . . . . . . . . . . . . . . . . . . . 1
CONTENTS
Controller Preparation . . . . . . . . . . . . . . . 13
View Preparation . . . . . . . . . . . . . . . . . . 27
Login and Logout . . . . . . . . . . . . . . . . . . 33Login . . . . . . . . . . . . . . . . . . . . . . . 33Logout . . . . . . . . . . . . . . . . . . . . . . . 37
Epilogue . . . . . . . . . . . . . . . . . . . . . . . 38
IntroductionNearly all web application needs some kind of user han-dling functionality. User handling could be simple likea rod, or a really sophisticated and complicated system.Sometimes we will have only one user, who could add newthings, edit and delete them in our application. Sometimeswe have to handle many users, different permissions, rolesand groups and do it as comfortable as possible. LuckilyCakePHP offers a great help in our work by its Authcomponent.
About the BookI wrote this book for CakePHP developers who want toknow how to handle users and user related functions. Forpeople who do not want to reinvent the wheel but wantsflexibility and like to write their own code using bestpractices.
The examples in this book use CakePHP, but the presentedideas themselves are not framework or language specific.
Why I Wrote This Book
I started to use CakePHP at version 1.1. The framework iswonderful, and improving nicely, with an open and helpfulstaff and community. It helped me to became a betterprogrammer.
When I started to code, I did everything from scratch. Idid not know about programming patterns, utilities, orlibraries. I was able to build up middle size systems thisway.
After a while, I decided that mixing application logic andpresentation logic has more cons than pros, so I started touse Smarty¹. Smarty was a great help. In time it helped me
¹http://smarty.net/
About the Book iii
to see thatmy best practices were reallymyworst practices.I knew I needed something more.
I realized there are a few features I need in most of myweb applications. I started to think about how I code andafter some time came up with an extremely simple and dullframework, without really knowing that frameworks exist.
That was when I heard about MVC pattern. At first itseemed like unnecessary complications in the code, but Iwanted to give it a try anyway. When I tried to understandMVC, I found some information about frameworks. I triedCodeIgniter², and then CakePHP³.
The first bite of CakePHP was awful. Especially becauseI was (and am) a big fan of bake auto code generation. Ithought that the whole framework just saved so much timeand produced a much clearer and more maintainable code.
CakePHP has a lot of built-in functionality, including au-thentication. It is clear, well written, easy to use. Stillwe tend to forget what we did last time, how we solveddifferent problems. I think many of you have had similarexperiences. Let’s try to shorten our learning curve.
I hope this book will help you and that my suggestions cansave you some time.
²http://ellislab.com/codeigniter³http://cakephp.org
About the Book iv
My Development Environment
I tried to use code examples that are independent from theenvironment but, as we all know, this is impossible. Withthat in mind, this is my system and the software I’m using.
• Ubuntu 14.04• PHP 5.5.9-1ubuntu4.4• CakePHP 2.5• MySQL 5.5.38• Komodo Edit 8.5• phpMyAdmin 4.0.10
Who This Book Is For
This book is for novice and intermediate programmers.
It assumes that you have a general understanding of PHPand object-oriented programming (OOP).
It’s good if you are already familiar with CakePHP. Buteven if you’re not, you will probably still be able to under-stand most of the principles and codes.
Prerequisites
I assume that you have already successfully installedCakePHP⁴,created a database for your application and set debug levelto 1 or 2.
⁴http://cakephp.org
About the Authorrrd started to code for the web in plain HTML in 1998. Asthe web evolved, he turned to PHP, then to Javascript. Asmobile technologies arrived, he started to play with Javafor android development.
He’s a big fan of CakePHP, jQuery, Prototype, and Scrip-taculous frameworks, open source, and pizza. All of themare there in his web development.
ThanksI would like to thank you for spending your time readingthis book.
I also should say thank you to the core CakePHP team andeverybody else who’s contributed anything, small or big,to this wonderful framework.
Finally, special thanks go to Italy for Pizza and to Hungaryfor Turo Rudi - both are essential for web development.
My E-books on CakePHP
CakePHP Unit Testing
CakePHP Unit Testing
Download from Leanpub⁵
⁵https://leanpub.com/cakephpunittesting
My E-books on CakePHP viii
CakePHP User Authentication
CakePHP User Authentication
Download from Leanpub⁶
⁶https://leanpub.com/CakePHPUserAuthentication
My CakePHP PluginsProtection against brute force attacks rBruteFore⁷
⁷https://github.com/rrd108/rBruteForce
Model Preparation
Creating User Table
We will need a user table in our database. Let’s create it.
1 CREATE TABLE `users` (
2 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
3 `email` varchar(255) NOT NULL,
4 `password` varchar(255) NOT NULL,
5 PRIMARY KEY (`id`),
6 UNIQUE KEY `email` (`email`)
7 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREM\
8 ENT=1;
As a start we have only 3 columns in our table, id, emailand password. The password will be stored encrypted, sothe field should be enough big.
Baking User
Our next step is to create a basic skeleton for our userhandling functionality. For this we should create our usermodel, view and controller. As always the easiest way to
Model Preparation 2
use CakePHP’s automatic code generation tool and bake
them.
Open a terminal and step into your application’s root direc-tory. Step into app/Console folder and type ./cake bake“.This will start CakePHP’s interactive bake console. bakeconsole is a smart and handy tool and it is self explanatory.If you do not familiar yet, we will walk through the wholeprocess, what normally takes 20 seconds.
Baking User Model
After starting bake console in your terminal window youwill see this.
1 Welcome to CakePHP v2.4.0 Console
2 ------------------------------------------------
3 App : app
4 Path: /home/rrd/public_html/blog/app/
5 ------------------------------------------------
6 Interactive bake Shell
7 ------------------------------------------------
8 [D]atabase Configuration
9 [M]odel
10 [V]iew
11 [C]ontroller
12 [P]roject
13 [F]ixture
14 [T]est case
15 [Q]uit
Model Preparation 3
First we bake our user model. Press m after the question“What would you like to bake?” appears. By this we startedto bake our user model.
1 What would you like to bake? (D/M/V/C/P/F/T/Q)
2 > m
3 ------------------------------------------------
4 `bake` Model
5 Path: /home/rrd/public_html/blog/app/Model/
6 ------------------------------------------------
Next we should choose which database schema should beused. Just press enter and it will select default.
1 Use Database Config: (default/test)
2 [default] >
After this we should tell to the bake script what modelwe want to create. Use the number in front of User. As incore.php I choose to use database for my sessions I shouldselect 2. If you did not changed this and left as default yourUser option will be 1. If you have more database tables thanchoose the number in the beginning of the User row.
Model Preparation 4
1 Possible Models based on your current database:
2 1. CakeSession
3 2. User
4 Enter a number from the list above,
5 type in the name of another model, or 'q' to exi\
6 t
7 [q] > 2
You should set your display field. CakePHP will use it inselect boxes. We do not need it in this phase so you couldpress n and let the bake script know that we will go withoutany display filed.
1 A displayField could not be automatically detect\
2 ed
3 would you like to choose one? (y/n)
4 > n
Perhaps we do not want to have useless data anywhere, sowe will use validation.
..
Validation is not a security check. Never forget tosanitize your input.
Model Preparation 5
1 Would you like to supply validation criteria
2 for the fields in your model? (y/n)
3 [y] >
After this the bake script will ask validation criteria foreach fields.
For the field id, we do not need any validation criteria, aswe will just let the database to auto increment its value. Soyou could just press enter and accept what the bake scriptoffers as default.
1 Field: id
2 Type: integer
3 ------------------------------------------------
4 Please select one of the following validation op\
5 tions:
6 ------------------------------------------------
7 1. alphanumeric 18. maxlength
8 2. between 19. mimetype
9 3. blank 20. minlength
10 4. boolean 21. money
11 5. cc 22. multiple
12 6. comparison 23. naturalnumber
13 7. custom 24. notempty
14 8. date 25. numeric
15 9. datetime 26. phone
16 10. decimal 27. postal
17 11. email 28. range
18 12. equalto 29. ssn
Model Preparation 6
19 13. extension 30. time
20 14. filesize 31. uploaderror
21 15. inlist 32. url
22 16. ip 33. userdefined
23 17. luhn 34. uuid
24
25 35 - Do not do any validation on this field.
26 ------------------------------------------------
27 ... or enter in a valid regex validation string.
28
29 [35] >
Next is the field email, what should looks like an emailaddress. Validation do not check if it is a real email ad-dress.Email addresses has their own built-in validationcriteria so we choose this.
1 Field: email
2 Type: string
3 ------------------------------------------------
4 Please select one of the following validation op\
5 tions:
6 ------------------------------------------------
7 1. alphanumeric 18. maxlength
8 2. between 19. mimetype
9 3. blank 20. minlength
10 4. boolean 21. money
11 5. cc 22. multiple
12 6. comparison 23. naturalnumber
Model Preparation 7
13 7. custom 24. notempty
14 8. date 25. numeric
15 9. datetime 26. phone
16 10. decimal 27. postal
17 11. email 28. range
18 12. equalto 29. ssn
19 13. extension 30. time
20 14. filesize 31. uploaderror
21 15. inlist 32. url
22 16. ip 33. userdefined
23 17. luhn 34. uuid
24
25 35 - Do not do any validation on this field.
26 ------------------------------------------------
27 ... or enter in a valid regex validation string.
28
29 [11] >
As we could have multiple validation criteria the bake
script asks if we would like to add an other. This time justpress enter at accept the default answer, no.
1 Would you like to add another validation rule? (\
2 y/n)
3 [n] >
For the password field we will have more criteria like itshould be more than 5 characters, etc. At this point we donot have to worry about this, we will add extra validationcriteria later. So just accept default answer.
Model Preparation 8
1 Field: password
2 Type: string
3 ------------------------------------------------
4 Please select one of the following validation op\
5 tions:
6 ------------------------------------------------
7 1. alphanumeric 18. maxlength
8 2. between 19. mimetype
9 3. blank 20. minlength
10 4. boolean 21. money
11 5. cc 22. multiple
12 6. comparison 23. naturalnumber
13 7. custom 24. notempty
14 8. date 25. numeric
15 9. datetime 26. phone
16 10. decimal 27. postal
17 11. email 28. range
18 12. equalto 29. ssn
19 13. extension 30. time
20 14. filesize 31. uploaderror
21 15. inlist 32. url
22 16. ip 33. userdefined
23 17. luhn 34. uuid
24
25 35 - Do not do any validation on this field.
26 ------------------------------------------------
27 ... or enter in a valid regex validation string.
28
29 [24] >
Model Preparation 9
30 Would you like to add another validation rule? (\
31 y/n)
32 [n] >
We do not have more fields, so bake moves forward andasks about model relationships. In this example app we donot have any model relations so we could press n.
1 Would you like to define model associations
2 (hasMany, hasOne, belongsTo, etc.)? (y/n)
3 [y] > n
Finally bake gives us a summary. Press enter.
1 ------------------------------------------------
2 The following Model will be created:
3 ------------------------------------------------
4 Name: User
5 DB Table: `blog`.`users`
6 Validation: Array
7 (
8 [email] => Array
9 (
10 [email] => email
11 )
12
13 [password] => Array
14 (
Model Preparation 10
15 [notempty] => notempty
16 )
17
18 )
19
20 ------------------------------------------------
21 Look okay? (y/n)
22 [y] >
After this CakePHP try to create our User Model. If it issuccessful you will see something like this.
1 Baking model class for User...
2
3 Creating file /home/rrd/public_html/blog/app/Mod\
4 el/User.php
5 Wrote `/home/rrd/public_html/blog/app/Model/User\
6 .php`
Last question is about unit testing. This timewe do not needunit tests, so press n.
Unit testing is an extremely useful tool insoftware development. Please read my bookCakePHP Unit Testing if you are interested.
Model Preparation 11
1 PHPUnit is not installed. Do you want to bake un\
2 it test files anyway? (y/n)
3 [y] > n
Now you could open your automatically generated /app/-Model/User.php file.
1 <?php
2 App::uses('AppModel', 'Model');
3 /**
4 * User Model
5 *
6 */
7 class User extends AppModel {
8
9 /**
10 * Validation rules
11 *
12 * @var array
13 */
14 public $validate = array(
15 'email' => array(
16 'email' => array(
17 'rule' => array('email'),
18 //'message' => 'Your custom message here\
19 ',
20 //'allowEmpty' => false,
21 //'required' => false,
22 //'last' => false, // Stop validation af\
Model Preparation 12
23 ter this rule
24 //'on' => 'create', // Limit validation \
25 to 'create' or 'update' operations
26 ),
27 ),
28 'password' => array(
29 'notempty' => array(
30 'rule' => array('notempty'),
31 //'message' => 'Your custom message here\
32 ',
33 //'allowEmpty' => false,
34 //'required' => false,
35 //'last' => false, // Stop validation af\
36 ter this rule
37 //'on' => 'create', // Limit validation \
38 to 'create' or 'update' operations
39 ),
40 ),
41 );
42 }
43 ?>
Controller PreparationCreate a basic controller with CRUD functions is also areally simple and straightforward process. It will take another 20 seconds.
If you did not closed your bake terminal you could justcontinue. If you did please start it again. This time youshould press c at the first step. By that the bake script willauto generate your controller code.
1 ------------------------------------------------
2 Interactive Bake Shell
3 ------------------------------------------------
4 [D]atabase Configuration
5 [M]odel
6 [V]iew
7 [C]ontroller
8 [P]roject
9 [F]ixture
10 [T]est case
11 [Q]uit
12 What would you like to Bake? (D/M/V/C/P/F/T/Q)
13 > c
As we did for our model we should choose which database
Controller Preparation 14
to use, and what controller we want to build. Chose defautdatabase and Users controller.
1 ------------------------------------------------
2 Bake Controller
3 Path: /home/rrd/public_html/blog/app/Controller/
4 ------------------------------------------------
5 Use Database Config: (default/test)
6 [default] >
7 Possible Controllers based on your current datab\
8 ase:
9 ------------------------------------------------
10 1. CakeSessions
11 2. Users
12 Enter a number from the list above,
13 type in the name of another controller, or 'q' t\
14 o exit
15 [q] > 2
The bake script could build your controller interactivelyor silently. I prefer to use the interactive shell, as there isa good chance that we want to change at least one thingfrom default to something else. So press enter and acceptthe default answer.
Controller Preparation 15
1 ------------------------------------------------
2 Baking UsersController
3 ------------------------------------------------
4 Would you like to build your controller interact\
5 ively? (y/n)
6 [y] >
Scaffolding is an extremely good way to have a workingbasic web application in a few minutes. As we will changethe controller code soon chose n. By this the bake script willgenerate the code and will not use scaffolds.
1 Would you like to use dynamic scaffolding? (y/n)
2 [n] >
Next bake asks about creating basic CRUD functions. Choosey. This will generate controller functions for adding, view-ing, editing and listing users.
1 Would you like to create some basic class method\
2 s
3 (index(), add(), view(), edit())? (y/n)
4 [n] > y
Admin routing helps you differentiate between regularusers and admins. It means you will have different CRUDfunctions for admins and for regular users in your con-troller. It is not a must have, you could code the samething without admin routes, but this is a more clear andmaintainable way. So press y for admin routing.
Controller Preparation 16
1 Would you like to create the basic class methods\
2 for admin routing? (y/n)
3 [n] > y
The bake script will add basic helpers to your controller.Press enter and accept default answer. If we will need morehelpers we would add them in our controller code later.
1 Would you like this controller to use other help\
2 ers
3 besides HtmlHelper and FormHelper? (y/n)
4 [n] >
Next question is about components. At this step we couldjust accept the default.
1 Would you like this controller to use other comp\
2 onents
3 besides PaginatorComponent? (y/n)
4 [n] >
We need to show flash messages, so choose yes for the nextquestion.
1 Would you like to use Session flash messages? (y\
2 /n)
3 [y] >
Aswe choose to use admin routeswe should edit /app/Config/core.phpand switch it on. You could change the routing prefix fromadmin to anything you like.
Controller Preparation 17
1 ------------------------------------------------
2 You need to enable Configure::write('Routing.pre\
3 fixes', array('admin')) in /app/Config/core.php \
4 to use prefix routing.
5 What would you like the prefix route to be?
6 Example: www.example.com/admin/controller
7 Enter a routing prefix:
8 [admin] >
Finally bake gives us a summary. Press enter.
1 ------------------------------------------------
2 The following controller will be created:
3 ------------------------------------------------
4 Controller Name:
5 Users
6 Components:
7 Paginator
8 ------------------------------------------------
9 Look okay? (y/n)
10 [y] >
11
12 Baking controller class for Users...
13
14 Creating file /home/rrd/public_html/blog/app/Con\
15 troller/UsersController.php
Last question is about unit testing. This timewe do not needunit tests, so press n.
Controller Preparation 18
Unit testing is an extremely useful tool insoftware development. Please read my bookCakePHP Unit Testing if you are interested.
1 Wrote `/home/rrd/public_html/blog/app/Controller\
2 /UsersController.php`
3 PHPUnit is not installed. Do you want to bake un\
4 it test files anyway? (y/n)
5 [y] > n
Now app/Controller/UsersController.php is generatedand you could open it with your favorite text editor.
1 <?php
2 App::uses('AppController', 'Controller');
3 /**
4 * Users Controller
5 *
6 * @property User $User
7 * @property PaginatorComponent $Paginator
8 */
9 class UsersController extends AppController {
10
11 /**
12 * Components
13 *
14 * @var array
15 */
Controller Preparation 19
16 public $components = array('Paginator');
17
18 /**
19 * index method
20 *
21 * @return void
22 */
23 public function index() {
24 $this->User->recursive = 0;
25 $this->set('users', $this->Paginator->pagina\
26 te());
27 }
28
29 /**
30 * view method
31 *
32 * @throws NotFoundException
33 * @param string $id
34 * @return void
35 */
36 public function view($id = null) {
37 if (!$this->User->exists($id)) {
38 throw new NotFoundException(__('Invalid us\
39 er'));
40 }
41 $options = array('conditions' => array('User\
42 .' . $this->User->primaryKey => $id));
43 $this->set('user', $this->User->find('first'\
44 , $options));
Controller Preparation 20
45 }
46
47 /**
48 * add method
49 *
50 * @return void
51 */
52 public function add() {
53 if ($this->request->is('post')) {
54 $this->User->create();
55 if ($this->User->save($this->request->data\
56 )) {
57 $this->Session->setFlash(__('The user ha\
58 s been saved.'));
59 return $this->redirect(array('action' =>\
60 'index'));
61 } else {
62 $this->Session->setFlash(__('The user co\
63 uld not be saved. Please, try again.'));
64 }
65 }
66 }
67
68 /**
69 * edit method
70 *
71 * @throws NotFoundException
72 * @param string $id
73 * @return void
Controller Preparation 21
74 */
75 public function edit($id = null) {
76 if (!$this->User->exists($id)) {
77 throw new NotFoundException(__('Invalid us\
78 er'));
79 }
80 if ($this->request->is('post') || $this->req\
81 uest->is('put')) {
82 if ($this->User->save($this->request->data\
83 )) {
84 $this->Session->setFlash(__('The user ha\
85 s been saved.'));
86 return $this->redirect(array('action' =>\
87 'index'));
88 } else {
89 $this->Session->setFlash(__('The user co\
90 uld not be saved. Please, try again.'));
91 }
92 } else {
93 $options = array('conditions' => array('Us\
94 er.' . $this->User->primaryKey => $id));
95 $this->request->data = $this->User->find('\
96 first', $options);
97 }
98 }
99
100 /**
101 * delete method
102 *
Controller Preparation 22
103 * @throws NotFoundException
104 * @param string $id
105 * @return void
106 */
107 public function delete($id = null) {
108 $this->User->id = $id;
109 if (!$this->User->exists()) {
110 throw new NotFoundException(__('Invalid us\
111 er'));
112 }
113 $this->request->onlyAllow('post', 'delete');
114 if ($this->User->delete()) {
115 $this->Session->setFlash(__('The user has \
116 been deleted.'));
117 } else {
118 $this->Session->setFlash(__('The user coul\
119 d not be deleted. Please, try again.'));
120 }
121 return $this->redirect(array('action' => 'in\
122 dex'));
123 }
124
125 /**
126 * admin_index method
127 *
128 * @return void
129 */
130 public function admin_index() {
131 $this->User->recursive = 0;
Controller Preparation 23
132 $this->set('users', $this->Paginator->pagina\
133 te());
134 }
135
136 /**
137 * admin_view method
138 *
139 * @throws NotFoundException
140 * @param string $id
141 * @return void
142 */
143 public function admin_view($id = null) {
144 if (!$this->User->exists($id)) {
145 throw new NotFoundException(__('Invalid us\
146 er'));
147 }
148 $options = array('conditions' => array('User\
149 .' . $this->User->primaryKey => $id));
150 $this->set('user', $this->User->find('first'\
151 , $options));
152 }
153
154 /**
155 * admin_add method
156 *
157 * @return void
158 */
159 public function admin_add() {
160 if ($this->request->is('post')) {
Controller Preparation 24
161 $this->User->create();
162 if ($this->User->save($this->request->data\
163 )) {
164 $this->Session->setFlash(__('The user ha\
165 s been saved.'));
166 return $this->redirect(array('action' =>\
167 'index'));
168 } else {
169 $this->Session->setFlash(__('The user co\
170 uld not be saved. Please, try again.'));
171 }
172 }
173 }
174
175 /**
176 * admin_edit method
177 *
178 * @throws NotFoundException
179 * @param string $id
180 * @return void
181 */
182 public function admin_edit($id = null) {
183 if (!$this->User->exists($id)) {
184 throw new NotFoundException(__('Invalid us\
185 er'));
186 }
187 if ($this->request->is('post') || $this->req\
188 uest->is('put')) {
189 if ($this->User->save($this->request->data\
Controller Preparation 25
190 )) {
191 $this->Session->setFlash(__('The user ha\
192 s been saved.'));
193 return $this->redirect(array('action' =>\
194 'index'));
195 } else {
196 $this->Session->setFlash(__('The user co\
197 uld not be saved. Please, try again.'));
198 }
199 } else {
200 $options = array('conditions' => array('Us\
201 er.' . $this->User->primaryKey => $id));
202 $this->request->data = $this->User->find('\
203 first', $options);
204 }
205 }
206
207 /**
208 * admin_delete method
209 *
210 * @throws NotFoundException
211 * @param string $id
212 * @return void
213 */
214 public function admin_delete($id = null) {
215 $this->User->id = $id;
216 if (!$this->User->exists()) {
217 throw new NotFoundException(__('Invalid us\
218 er'));
Controller Preparation 26
219 }
220 $this->request->onlyAllow('post', 'delete');
221 if ($this->User->delete()) {
222 $this->Session->setFlash(__('The user has \
223 been deleted.'));
224 } else {
225 $this->Session->setFlash(__('The user coul\
226 d not be deleted. Please, try again.'));
227 }
228 return $this->redirect(array('action' => 'in\
229 dex'));
230 }
231 }
You will notice plain and admin CRUD functions aregenerated and the code are the same in them. Do not worryabout this, we will get back to them in a short time.
View PreparationWe should bake our user views also. It is just as simple asfor models and controllers. Go back to your bake consoleand choose v for generating views.
1 ------------------------------------------------
2 Interactive Bake Shell
3 ------------------------------------------------
4 [D]atabase Configuration
5 [M]odel
6 [V]iew
7 [C]ontroller
8 [P]roject
9 [F]ixture
10 [T]est case
11 [Q]uit
12 What would you like to Bake? (D/M/V/C/P/F/T/Q)
13 > v
As we did earlier we should choose the database and thecontroller for which we create the views.
View Preparation 28
1 ------------------------------------------------
2 Bake View
3 Path: /home/rrd/public_html/blog/app/View/
4 ------------------------------------------------
5 Use Database Config: (default/test)
6 [default] >
7 Possible Controllers based on your current datab\
8 ase:
9 ------------------------------------------------
10 1. CakeSessions
11 2. Users
12 Enter a number from the list above,
13 type in the name of another controller, or 'q' t\
14 o exit
15 [q] > 2
We choose interactive mode as we did for the controller.
1 Would you like bake to build your views interact\
2 ively?
3 Warning: Choosing no will overwrite Users views \
4 if it exist. (y/n)
5 [n] > y
As we already generated controller CRUD functions nowwe could generate their corresponding views.
View Preparation 29
1 Would you like to create some CRUD views
2 (index, add, view, edit) for this controller?
3 NOTE: Before doing so, you'll need to create you\
4 r controller
5 and model classes (including associated models).\
6 (y/n)
7 [y] >
And we also generate views for admin functions.
1 Would you like to create the views for admin rou\
2 ting? (y/n)
3 [n] > y
The bake script now actually generate the files and writesthem to our hard drive.
1 Baking `index` view file...
2
3 Creating file /home/rrd/public_html/blog/app/Vie\
4 w/Users/index.ctp
5 Wrote `/home/rrd/public_html/blog/app/View/Users\
6 /index.ctp`
7
8 Baking `view` view file...
9
10 Creating file /home/rrd/public_html/blog/app/Vie\
11 w/Users/view.ctp
View Preparation 30
12 Wrote `/home/rrd/public_html/blog/app/View/Users\
13 /view.ctp`
14
15 Baking `add` view file...
16
17 Creating file /home/rrd/public_html/blog/app/Vie\
18 w/Users/add.ctp
19 Wrote `/home/rrd/public_html/blog/app/View/Users\
20 /add.ctp`
21
22 Baking `edit` view file...
23
24 Creating file /home/rrd/public_html/blog/app/Vie\
25 w/Users/edit.ctp
26 Wrote `/home/rrd/public_html/blog/app/View/Users\
27 /edit.ctp`
28
29 Baking `admin_index` view file...
30
31 Creating file /home/rrd/public_html/blog/app/Vie\
32 w/Users/admin_index.ctp
33 Wrote `/home/rrd/public_html/blog/app/View/Users\
34 /admin_index.ctp`
35
36 Baking `admin_view` view file...
37
38 Creating file /home/rrd/public_html/blog/app/Vie\
39 w/Users/admin_view.ctp
40 Wrote `/home/rrd/public_html/blog/app/View/Users\
View Preparation 31
41 /admin_view.ctp`
42
43 Baking `admin_add` view file...
44
45 Creating file /home/rrd/public_html/blog/app/Vie\
46 w/Users/admin_add.ctp
47 Wrote `/home/rrd/public_html/blog/app/View/Users\
48 /admin_add.ctp`
49
50 Baking `admin_edit` view file...
51
52 Creating file /home/rrd/public_html/blog/app/Vie\
53 w/Users/admin_edit.ctp
54 Wrote `/home/rrd/public_html/blog/app/View/Users\
55 /admin_edit.ctp`
When it is ready you could open your view files and seethe generated code. So we spent again 20 seconds withCakePHP automatic code generating tool bake.
Now if you navigate your browser to your app (in my caseit is at http://localhost/∼rrd/blog/) and type users tothe end of the url you should see the following screen.
View Preparation 32
Users Controller After Baking
You should be able to add, edit, delete and view users. Aswe generated validation rules your input will be validatedagainst them. So if you try to add a new user with a nonvalid email address the app should reject it.
Login and LogoutSo now we are able to create, edit, delete and list users.Better to say now anyone could do this things. So if anyonefinds your application on the web will able to create newusers, delete existing users and edit all users’ data. Clearlythis is not what we want.
We have to know who plays in our application. For this weshould log the user in.
Login
Login - controller
Let’s create our loginmethod in our User controller. Open/app/Controller/UsersController.php and the follow-ing method.
Login and Logout 34
1 public function login() {
2 if ($this->request->is('post')) {
3 if ($this->Auth->login()) {
4 return $this->redirect($this->Auth->redire\
5 ctUrl());
6 }
7 else {
8 $this->Session->setFlash(__('Username or p\
9 assword is incorrect'), 'default', array(), 'aut\
10 h');
11 }
12 }
13 }
As we would like to use Auth component in our controllerwe should add it to the controller’s $components array.The best place for this is AppController.php. So replace the$components array with this.
1 public $components = array('Session', 'Auth');
CakePHP conventions are really handy but sometimes wewant to use something else. The Auth component waitingfor username and password fields. We use email and notusername so we should set up the Auth component tohandle this. Without this setting it will not log us in evenwith the right email password combination.
Open UsersController.php and at the beginning change$components array.
Login and Logout 35
1 public $components = array(
2 'Paginator',
3 'Auth' => array(
4 'authenticate' => array(
5 'Form' => array(
6 'fields' => array('username' => 'email')
7 )
8 )
9 )
10 );
Login - view
We should create the login view with two input field forthe e-mail address and the password.
1 <div class="users form">
2 <?php echo $this->Form->create('User', array('ac\
3 tion' => 'login')); ?>
4 <fieldset>
5 <legend><?php echo __('Login'); ?></legend>
6 <?php
7 echo $this->Form->input('email');
8 echo $this->Form->input('password');
9 ?>
10 </fieldset>
11 <?php echo $this->Form->end(__('Login')); ?>
12 </div>
Login and Logout 36
We would like to show error messages to the user. Iprefer to have all error messages at the same place, be-cause it improves usability. So open your default.ctp atapp/View/Layouts and add the following line somewhere.I recommend to put to the top of the content div.
1 <?php echo $this->Session->flash('auth'); ?>
At this point we should able to log in. Thanks to Auth if wetry to open any url it will automatically redirect us to thelogin page and on successful login we will be redirected tothe original url.
From nowwithout logging in nobody could access any partof our application except the login page.
Usability
Usability requires informing the user about successful loginor about the fact he or she is already logged in. A bestpractice is to put a message to the top of the page.
Open default.ctp at app/View/Layouts and add this tothe header div.
Login and Logout 37
1 if($this->Session->read('Auth.User.id')){
2 print 'Hi ' . $this->Session->read('Auth.User.\
3 email') . ' ' . $this->Html->link('Logout', arra\
4 y('controller' => 'users', 'action' => 'logout')\
5 );
6 }
7 else{
8 print $this->Html->link('Login', array('contro\
9 ller' => 'users', 'action' => 'login'));
10 }
Logout
Perhapswe need a logoutmethod to UsersController.php.
1 function logout(){
2 $this->redirect($this->Auth->logout());
3 }
EpilogueI hope by reading this e-book your main questions aboutuser authentication is answered. Perhaps I could write thisbook double or triple in size if I going to cover everythingrelated to this topic. My purpose was to represent theidea itself, and I am pretty sure that you could easily findsolutions to your further questions.
Happy coding.