Download Login and Registration code in CakePHP3

In this tutorial, you will learn how to make a login and registration system using CakePHP 3 and Auth component. I had made in previous tutorial simple CRUD system in CakePHP3 where you can add, get, delete and update topics. I will improve it to have a restriction that no one can add or edit without login as a registered user. It is very important in ecommerce or login based website to store the user information for further use. Here we will show both login and registration in cakephp3.

(You can also read : Download Login Form in PHP and Mysql)

First step :

App database has two tables :

users table where we store registered users data.

CREATE TABLE `users` (
  `id` int(14) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `name` varchar(50) NOT NULL,
  `username` varchar(50) NOT NULL,
  `password` varchar(255) NOT NULL,
  `email` varchar(50) NOT NULL,
  `phone` varchar(25) NOT NULL,
  `birthdate` date NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Create topics table it saves users’ topics.

CREATE TABLE `topics` (
  `id` int(14) UNSIGNED NOT NULL,
  `user_id` int(14) NOT NULL,
  `title` varchar(150) NOT NULL,
  `content` text NOT NULL,
  `tags` varchar(255) NOT NULL,
  `author` varchar(100) NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Step2 : Create the models :

Create TopicsTable.php in \model\Table\ path. As many topics can be written by a user, we will associate the two tables ; Topics and Users  using CakePHP associations. So, in TopicsTable class we will use belongsTo relation .It means that many topics have one user.

<?php

namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;

classTopicsTable extends Table
{
	public function initialize(array $config)
		{
		$this->addBehavior('Timestamp');
		$this->belongsTo('Users', [
		'foreignKey' => 'user_id',
		]);
	}
	public function isOwnedBy($topicId, $userId)
	{
		return $this->exists(['id' => $topicId, 'user_id' => $userId]);
	}
}
?>

isOwnedBy() method  checks if a topic with specific id has the given $userId parameter  value in user_id field .We will use it in authorizing to prevent unauthorized people from editing or deleting others topics .

Create UsersTable.php in \model\Table\ path. We will add a hasMany relation between UsersTable and TopicsTable. It means that one user can have many topics.

<?php

namespace App\Model\Table;
use App\Model\Entity\User;
use Cake\ORM\Table;
use Cake\Validation\Validator;

classUsersTable extends Table {
	public function initialize(array $config){
		$this->addBehavior("Timestamp");
		$this->hasMany('Users', [
            'foreignKey' => 'user_id'
        ]);
			
	}
	public function validationDefault(Validator $validator){
		 $validator->requirePresence('name','You must enter your name')
					 ->add('name', [
						'length' => [
						'rule' => ['minLength', 6],
						'message' => 'Name need to be at least 6 characters long',
						]
					])
					->notEmpty('name','Please, enter your name !')
					->notEmpty('password','Please, enter your password !')
					->add('password', [
					'compare' => [
						'rule' => ['compareWith', 'password2'],
						'message'=>"Password mismatch password confirm !"
						]
					])
					->notEmpty('email','Please, enter your email  !')
					->add('email', [
					'email' => [
						'rule' => ['email'],
						'message'=>" Please, enter a valid email!"
						]
					])						
					->numeric('phone','Please, enter valid phone number !')		
					->date('birthdate','Please, enter valid bith date !')		
					return $validator;																
	}
	
	
	public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->isUnique(['email']));
return $rules;
    }
}
?>

buildRules() function returns a rules checker object . It is used  for validating data. I used it her to check if email is unique.

Step 3 : Create the controllers :

Change the AppControllerclass to load AuthComponent. AuthComponent is a CakePHP class that control login, actions allowed for unauthenticated visitors , and authorizing users to their allowed actions.

You can configure Auth component by using config arrays.

We will make authenticating by ‘email’ and ‘password’ fields. The action of login will be ‘users/login’. If any user goes to edit oradds topics without logging in, he will be redirected to that action to login first.

When user logout, he will be redirected to ‘topics/index’ action. We will allow visitors without authentication to visit index and view actions .

<?php

namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Event\Event;


classAppController extends Controller
{


public function initialize()
    {
        parent::initialize();
        $this->loadComponent('RequestHandler');
		$this->loadComponent('Flash');
		$this->loadComponent('Auth', [
		'authorize'=> 'Controller',
		'authenticate' => [
			'Form' => [
				// fields used in login form
				'fields' => [
					'username' => 'email',
					'password' => 'password'
				]
			]
		],
		// login Url
		'loginAction' => [
			'controller' => 'Users',
			'action' => 'login'
		],
		// where to be redirected after logout  
		'logoutRedirect' => [
			'controller' => 'Topics',
			'action' => 'index'//,
			//'home'
		],
		// if unauthorized user go to an unallowed action he will be redirected to this url
		'unauthorizedRedirect' => [
			'controller' => 'Topics',
			'action' => 'index'//,
			//'home'
		],
		'authError' => 'Did you really think you are allowed to see that?',
		]);
		// Allow the display action so our pages controller still works and  user can visit index and view actions.
		$this->Auth->allow(['index','display','view']);
		
    }


	public function isAuthorized($user)
	{
		$this->Flash->error('You aren\'t allowed');
		return false;
	}
	
	public function beforeFilter(Event $event)
	{
		$this->Auth->allow(['index', 'view', 'display']);
	}

	
public function beforeRender(Event $event)
    {
if (!array_key_exists('_serialize', $this->viewVars) &&
in_array($this->response->type(), ['application/json', 'application/xml'])
        ) {
            $this->set('_serialize', true);
        }
    }
}


?>

isAuthorized() method is used in restricting the topics access .It will work with isAuthorized() method in controllers to allow authorized users and prevent others.

Create UsersContoller.php in \Controller\ path.

loginaction allows users to login. It uses Auth component to identify users by login request data.
setUser() method : saves registered user data  in Auth component.

logout action : logged-in user logout using Auth component, then redirected to ‘logoutRedirect’ specified in Auth component.

<?php
namespace App\Controller;

use App\Controller\AppController;

classUsersController extends AppController{

public function initialize()
    {
        parent::initialize();
		$this->loadComponent('Flash'); // Include the FlashComponent
		// Auth component allow visitors to access add action to register  and access logout action 
		$this->Auth->allow(['logout', 'add']);

    }
	
	public function login()
	{
		if ($this->request->is('post')) {
			// Auth component identify if sent user data belongs to a user
			$user = $this->Auth->identify();
			if ($user) {
				//
				$this->Auth->setUser($user);
				return $this->redirect($this->Auth->redirectUrl());
			}
			$this->Flash->error(__('Invalid username or password, try again.'));
		}
	}
	
	public function logout(){
		$this->Flash->success('You successfully have loged out');	
	return	$this->redirect($this->Auth->logout());
	}
	public function index()
	{
		$this->set('users',$this->Users->find('all'));		
	}
	public function view($id)
	{
		$user = $this->Users->get($id);
		$this->set('user',$user);
		
	}
	public function add()
	{
		$user = $this->Users->newEntity();
		if($this->request->is('post')) {
			$this->Users->patchEntity($user,$this->request->data);
			if($this->Users->save($user)){
            $this->Flash->success(__('Your account has been registered .'));
return $this->redirect(['action' => 'index']);
			}
			$this->Flash->error(__('Unable to register your account.'));
		}
		$this->set('user',$user);
	}
	public function edit($id)
	{
		$user = $this->Users->get($id);
		if ($this->request->is(['post', 'put'])) {
			$this->Users->patchEntity($user, $this->request->data);
			if ($this->Users->save($user)) {
				$this->Flash->success(__('Your profile data has been updated.'));
				return $this->redirect(['action' => 'index']);
			}
			$this->Flash->error(__('Unable to update your profile.'));
		}
	
		$this->set('user', $user);		
		
	}
	public function delete($id)
	{
		$this->request->allowMethod(['post', 'delete']);
	
		$user = $this->Users->get($id);
		if ($this->Users->delete($user)) {
			$this->Flash->success(__('The user with id: {0} has been deleted.', h($id)));
			return $this->redirect(['action' => 'index']);
		}		
		
	}	
}
?>

Create TopicsContoller class in /Contoller/ path

<?php
namespace App\Controller;

use App\Controller\AppController;
use Cake\Cache\Cache;
classTopicsController extends AppController
{

public function initialize()
    {

        parent::initialize();

        $this->loadComponent('Flash'); // Include the FlashComponent

				
    }
	public function isAuthorized($user)
	{
		$action = $this->request->params['action'];
		//  registered users can add topics and view index
		if (in_array($action, ['index', 'add','topics'])) {
		return true;
		}
		// All other actions require an id or users cannot do it 
		if (empty($this->request->params['pass'][0])) {
			return false;
		}		
		
		// The owner of a topic can edit and delete it
		// the owner of topic is known by its id and user_id value of topic .
		if (in_array($this->request->action, ['edit', 'delete'])) {
		// get topic id from the request 	
		$topicId = (int)$this->request->params['pass'][0];
		// check if the topic is owned by the user 
		if ($this->Topics->isOwnedBy($topicId, $user['id'])) {
		return true;
		}
		}
		return parent::isAuthorized($user);


	}

public function index()
    {
		// find('all') get all records from Topics model
		// We uses set() to pass data to view 
        $this->set('topics', $this->Topics->find('all'));
    }

public function view($id)
    {
		// get() method get only one topic record using 
		// the $id paraameter is received from the requested url
		// if request is /topics/view/5   the $id parameter value is 3
        $topic = $this->Topics->get($id);
        $this->set(compact('topic'));
    }

public function add()
    {
        $topic = $this->Topics->newEntity();
		//if the user topics data to your application, the POST request  informations are registered in $this->request   
if ($this->request->is('post')) { // 
            $topic = $this->Topics->patchEntity($topic, $this->request->data);
			$topic->user_id = $this->Auth->user('id');
if ($this->Topics->save($topic)) {
				// success() method of FlashComponent restore messages in session variable.
				// Flash messages are displayed in views 
                $this->Flash->success(__('Your topic has been saved.'));
return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('Unable to add your topic.'));
        }
        $this->set('topic', $topic);
    }
	public function edit($id = null)
	{
		$topic = $this->Topics->get($id);
		if ($this->request->is(['post', 'put'])) {
			$this->Topics->patchEntity($topic, $this->request->data);
			if ($this->Topics->save($topic)) {
				$this->Flash->success(__('Your topic has been updated.'));
				return $this->redirect(['action' => 'index']);
			}
			$this->Flash->error(__('Unable to update your topic.'));
		}
	
		$this->set('topic', $topic);
	}
	public function delete($id)
	{
		//if user wants to delete a record by a GET request ,allowMethod() method give an Exception as the only available request for deleting is POST
		$this->request->allowMethod(['post', 'delete']);
	
		$topic = $this->Topics->get($id);
		if ($this->Topics->delete($topic)) {
			$this->Flash->success(__('The topic with id: {0} has been deleted.', h($id)));
			return $this->redirect(['action' => 'index']);
		}
	}
}
?>

isAuthorized() function check which user can do what or cannot.

Step 4 : create views :

In /Templates/ path create ‘/Templates/Topics’ folder . Inside it create :index.ctp, view.ctp, add.ctp, and edit.ctp

/Templates/Topics/index.ctp

<h1>Blog topics</h1>
<p><?= $this->Html->link('Add Topic', ['action' => 'add']) ?></p>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Created</th>
<th>Actions</th>
</tr>

<!-- Here's where we loop through our $topics query object, printing out topic info -->

<?phpforeach ($topics as $topic): ?>
<tr>
<td><?= $topic->id ?></td>
<td>
<?= $this->Html->link($topic->title, ['action' => 'view', $topic->id]) ?>
</td>
<td>
<?= $topic->created->format(DATE_RFC850) ?>
</td>
<td>
<?= $this->Form->postLink(
                'Delete',
                ['action' => 'delete', $topic->id],
['confirm' => 'Are you sure?'])
            ?>
<?= $this->Html->link('Edit', ['action' => 'edit', $topic->id]) ?>
</td>
</tr>
<?phpendforeach; ?>
	<tr>
	<?php  if ($this->request->session()->read('Auth.User')){ ?>
		<td><?=$this->Html->Link(__('Log out'),['controller'=>'users','action'=>'logout']) ?></td>
	<?php }else{  ?>
		<td><?=$this->Html->Link(__('Login'),['controller'=>'users','action'=>'login']) ?></td>	
	<?php } ?>
	
	</tr>
</table>

/Templates/Topics/view.ctp

<h1><?= h($topic->title) ?></h1>
<p><?= h($topic->content) ?></p>

<p>Tags :<?= h($topic->tags) ?></p>
By <h3><?= h($topic->author) ?></h3>
<p><small>Created: <?= $topic->created->format(DATE_RFC850) ?></small></p>

/Templates/Topics/add.ctp

<h1>Add Topic</h1>
<?php
echo $this->Form->create($topic);
echo $this->Form->input('title');
echo $this->Form->input('content', ['rows' => '3']);
echo $this->Form->input('tags');	
echo $this->Form->input('author');	
echo $this->Form->button(__('Save Topic'));
echo $this->Form->end();
?>

/Templates/Topics/edit.ctp

<h1>Edit Topic</h1>
<?php
echo $this->Form->create($topic);
echo $this->Form->input('title');
echo $this->Form->input('content', ['rows' => '3']);
echo $this->Form->input('tags');	
echo $this->Form->input('author');	
echo $this->Form->button(__('Save Topic'));
echo $this->Form->end();
?>

/Templates/Topics/edit.ctpIn /Templates/ path create ‘/Templates/Users’ folder . Inside it create :login.ctp, index.ctp, view.ctp, add.ctp, and edit.ctp

/Templates/Topics/login.ctp

<h1> Login </h1>
<p>Enter your username & password: </p>
<?php echo $this->Form->create();
	echo $this->Form->input('email');
	echo $this->Form->input('password');
	echo $this->Form->button('Login');
	echo $this->Form->end() 
    ?>

/Templates/Topics/add.ctp

<h1>Register new user </h1>
<?php
echo $this->Flash->render('auth');
echo $this->Form->create($user);
echo $this->Form->input('name');
echo $this->Form->input('username');
echo $this->Form->input('password');		
echo $this->Form->input('password2',array('label'=>"confirm password",'type'=>'password'));	
echo $this->Form->input('email');
echo $this->Form->input('phone');	
echo $this->Form->input('birthdate',[
		'minYear' => date('Y') - 80,
		'maxYear' => date('Y') - 10
	]);	
		
		
echo $this->Form->button(__('Register'));
echo $this->Form->end();
?>

/Templates/Topics/edit.ctp

<h1>Edit user data </h1>
<?php

echo $this->Form->create($user);
echo $this->Form->input('name');
echo $this->Form->input('username');
	echo $this->Form->input('email');
	echo $this->Form->input('password');
	echo $this->Form->input('password2');		
echo $this->Form->input('phone');	
echo $this->Form->input('birthdate');		
echo $this->Form->button(__('Save'));
echo $this->Form->end();
?>

At the end of this article, you have learnt how Auth component work, Login &Registration in CakePHP, and authorization in CakePHP.  This tutorial needs concentration to grasp it. Read, write your app and feel free to write in comment section.

Share this Article on Social Media

All of my Scripts are ready to customized as per your requirement. Feel free to contact for script customization.

Contact me at discussdesk@gmail.com

"Note : It will be charged as per your customization requirement :)"

Get Updates, Scripts & Other Tutorials to Directly to your Email

Over 20000+ Happy Readers already subscribed. (We don't send spam email). Every email subscriber can get our latest updates and download our 100+ scripts.

Comments