Inicio Rápido

Instale el plugin con composer desde el directorio ROOT del Proyecto CakePHP (donde está localizado el archivo composer.json)

php composer.phar require "cakephp/authentication:^2.0"

Carge el plugin agregando la siguiente declaración en src/Application.php:

public function bootstrap(): void
{
    parent::bootstrap();

    $this->addPlugin('Authentication');
}

Empezando

El plugin authentication se integra con su aplicación como un middleware. También, se puede utilizar como un componente para simplificar el acceso no autenticado. Primero aplique el middleware. En src/Application.php, agregue las siguientes importaciones de clase:

use Authentication\AuthenticationService;
use Authentication\AuthenticationServiceInterface;
use Authentication\AuthenticationServiceProviderInterface;
use Authentication\Identifier\IdentifierInterface;
use Authentication\Middleware\AuthenticationMiddleware;
use Cake\Http\MiddlewareQueue;
use Cake\Routing\Router;
use Psr\Http\Message\ServerRequestInterface;

A continuación, agregue AuthenticationServiceProviderInterface a las interfaces implementadas en su aplicación:

class Application extends BaseApplication implements AuthenticationServiceProviderInterface

Luego agregue AuthenticationMiddleware a la cola de middleware en la función middleware():

$middlewareQueue->add(new AuthenticationMiddleware($this));

Nota

Asegúrese de agregar AuthenticationMiddleware antes de AuthorizationMiddleware si tiene ambos, y después de RoutingMiddleware.

AuthenticationMiddleware llamará a un método hook en su aplicación cuando comience a manejar la solicitud. Este método hook permite que su aplicación defina el AuthenticationService que quiere usar. Agregue el siguiente método a su src/Application.php:

/**
 * Returns a service provider instance.
 *
 * @param \Psr\Http\Message\ServerRequestInterface $request Request
 * @return \Authentication\AuthenticationServiceInterface
 */
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
    $service = new AuthenticationService();

    // Define where users should be redirected to when they are not authenticated
    $service->setConfig([
        'unauthenticatedRedirect' => Router::url([
                'prefix' => false,
                'plugin' => null,
                'controller' => 'Users',
                'action' => 'login',
        ]),
        'queryParam' => 'redirect',
    ]);

    $fields = [
        IdentifierInterface::CREDENTIAL_USERNAME => 'email',
        IdentifierInterface::CREDENTIAL_PASSWORD => 'password'
    ];
    // Load the authenticators. Session should be first.
    $service->loadAuthenticator('Authentication.Session');
    $service->loadAuthenticator('Authentication.Form', [
        'fields' => $fields,
        'loginUrl' => Router::url([
            'prefix' => false,
            'plugin' => null,
            'controller' => 'Users',
            'action' => 'login',
        ]),
    ]);

    // Load identifiers
    $service->loadIdentifier('Authentication.Password', compact('fields'));

    return $service;
}

En el bloque anterior, primero, configuramos qué hacer con los usuarios cuando no están autenticados. A continuación, adjuntamos la Session y el Form Autenticadores que definen los mecanismos que utilizará nuestra aplicación para autenticar usuarios. Session nos permite identificar a los usuarios en función de los datos de la sesión, mientras que Form nos permite gestionar un formulario de inicio de sesión en el loginUrl. Finalmente adjuntamos un identifier para convertir las credenciales que los usuarios nos darán en un identity que representa nuestro usuario registrado.

Si uno de los autenticadores configurados pudo validar las credenciales, el middleware agregará el servicio de autenticación al objeto request como un attribute.

A continuación, en su AppController cargue el Componente Authentication:

// in src/Controller/AppController.php
public function initialize()
{
    parent::initialize();

    $this->loadComponent('Authentication.Authentication');
}

De forma predeterminada, el componente requerirá un usuario autenticado para todas las acciones. Puede deshabilitar este comportamiento en controladores específicos usando allowUnauthenticated():

// in a controller beforeFilter or initialize
// Make view and index not require a logged in user.
$this->Authentication->allowUnauthenticated(['view', 'index']);

Creación de una acción Login

Una vez que haya aplicado el middleware a su aplicación, necesitará una forma para que los usuarios inicien sesión. Primero genere un modelo y un controlador de usuarios con bake:

bin/cake bake model Users
bin/cake bake controller Users

Luego, agregue una acción login a su UsersController. Debería verse así:

// in src/Controller/UsersController.php
public function login()
{
    $result = $this->Authentication->getResult();
    // If the user is logged in send them away.
    if ($result->isValid()) {
        $target = $this->Authentication->getLoginRedirect() ?? '/home';
        return $this->redirect($target);
    }
    if ($this->request->is('post')) {
        $this->Flash->error('Invalid username or password');
    }
}

Asegúrese de permitir el acceso a la acción login en su contralador en beforeFilter() callback como se menciona en la sección anterior, así los usuarios no autenticados puedan acceder a ella:

// in src/Controller/UsersController.php
public function beforeFilter(\Cake\Event\EventInterface $event)
{
    parent::beforeFilter($event);

    $this->Authentication->allowUnauthenticated(['login']);
}

A continuación, agregaremos un template para nuestro formulario login:

// in templates/Users/login.php
<div class="users form content">
    <?= $this->Form->create() ?>
    <fieldset>
        <legend><?= __('Please enter your email and password') ?></legend>
        <?= $this->Form->control('email') ?>
        <?= $this->Form->control('password') ?>
    </fieldset>
    <?= $this->Form->button(__('Login')); ?>
    <?= $this->Form->end() ?>
</div>

Luego agregue una acción logout:

// in src/Controller/UsersController.php
public function logout()
{
    $this->Authentication->logout();
    return $this->redirect(['controller' => 'Users', 'action' => 'login']);
}

No necesitamos un template para nuestra acción logout ya que redirigimos al final.

Adición de hash de contraseña

Para iniciar sesión, sus usuarios deberán tener contraseñas hash. Puede aplicar hash a las contraseñas automáticamente cuando los usuarios actualizan su contraseña mediante un método entity setter:

// in src/Model/Entity/User.php
use Authentication\PasswordHasher\DefaultPasswordHasher;

class User extends Entity
{
    // ... other methods

    // Automatically hash passwords when they are changed.
    protected function _setPassword(string $password)
    {
        $hasher = new DefaultPasswordHasher();
        return $hasher->hash($password);
    }
}

Ahora debería poder ir a /users/add y registrar un nuevo usuario. Una vez registrado, puede ir a /users/login iniciar sesión con su usuario recién creado.

Otras lecturas