Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 142 additions & 2 deletions en/tutorials-and-examples/cms/authentication.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,148 @@
CMS Tutorial - Authentication
#############################

* Adding login
* Adding logout
Now that our CMS has users, we should enable them to login, and apply some basic
access control to the article creation & editing experiences.

Adding Login
============

In CakePHP, authentication is handled by :doc:`/controllers/components`.
Components can be thought of as ways to create reusable chunks of controller
code related to a specific feature or concept. Components can hook into the
controller's event life-cycle and interact with your application that way. To
get started, we'll add the :doc:`AuthComponent
</controllers/components/authentication>` to our application. We'll want the
create, update and delete methods to require authentication, so we'll add
AuthComponent in our AppController::

// In src/Controller/AppController.php
namespace App\Controller;

use Cake\Controller\Controller;

class AppController extends Controller
{
public function initialize()
{
// Existing code

$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
// If unauthorized, return them to page they were just on
'unauthorizedRedirect' => $this->referer()
]);

// Allow the display action so our pages controller
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pages?? or all controller(s)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is all controllers.

// continues to work. Also enable the read only actions.
$this->Auth->allow(['display', 'view', 'index']);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this was baked, it has code it in at this point. Do you think including that code or a // existing code would be good? If using the // existing code, you can remove the FlashComponent as that is baked in. Here's the baked code if you want to include it instead:

    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');

        /*
         * Enable the following components for recommended CakePHP security settings.
         * see http://book.cakephp.org/3.0/en/controllers/components/security.html
         */
        //$this->loadComponent('Security');
        //$this->loadComponent('Csrf');
    }


We've just told CakePHP that we want to load the ``Flash`` and ``Auth``
components. In addition, we've customized the configuration of AuthComponent, as
our users table uses ``email`` as the username. Now, if you go any protected
URL, such as ``/articles/add``, you'll be redirected to **/users/login**, which
will show an error page as we have not written that code yet. So let's create
the login action::

// In src/Controller/UsersController.php
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error('Your username or password is incorrect.');
}
}

And in **src/Template/Users/login.ctp** add the following::

<h1>Login</h1>
<?= $this->Form->create() ?>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is not better to use entity object here?
$this->Form->create($user)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no entity though.

<?= $this->Form->control('email') ?>
<?= $this->Form->control('password') ?>
<?= $this->Form->button('Login') ?>
<?= $this->Form->end() ?>

.. note::

The ``control()`` method is available since 3.4. For prior versions you can
use the ``input()`` method instead.

Now that we have a simple login form, we should be able to log in with one of
the users that has a hashed password.

.. note::

If none of your users have hashed passwords, comment the
``loadComponent('Auth')`` block and ``$this->Auth->allow()`` calls. Then go
and edit the user, saving a new password for them. After saving a new
password for the user, make sure to uncomment the lines we just temporarily
commented!

Try it out! Before logging in, visit ``/articles/add``. Since this action is not
allowed, you will be redirected to the login page. After logging in
successfully, CakePHP will automatically redirect you back to ``/articles/add``.

Adding Logout
=============

Now that people can log in, you'll probably want to provide a way to log out as
well. Again, in the ``UsersController``, add the following code::

public function initialize()
{
parent::initialize();
$this->Auth->allow(['logout']);
}

public function logout()
{
$this->Flash->success('You are now logged out.');
return $this->redirect($this->Auth->logout());
}

This code adds the ``logout`` action to the list of actions that do not require
authentication and implements the logout method. Now you can visit
``/users/logout`` to log out. You should then be sent to the login page.

Enabling Registrations
======================

If you aren't logged in and you try to visit **/users/add** you will be
redirected to the login page. We should fix that as we want to allow people to
sign up for our application. In the ``UsersController`` add the following::

public function initialize()
{
parent::initialize();
// Add the 'add' action to the allowed actions list.
$this->Auth->allow(['logout', 'add']);
}

The above tells ``AuthComponent`` that the ``add()`` action of the
``UsersController`` does *not* require authentication or authorization. You may
want to take the time to clean up the **Users/add.ctp** and remove the
misleading links, or continue on to the next section. We won't be building out
user editing, viewing or listing in this tutorial, but that is an exercise you
can complete on your own.

* Enabling Access Control
* Updating Creation
* Restricting Editing