Authentication in CakePHP4 (Strawberry)

 

Adding Authentication:

Once you've included the Authentication class, you can get a user's information with the following:


//in any controller
$user = $this->Authentication->getIdentity()

Here's another helpful link: https://book.cakephp.org/4/en/controllers/components/security.html#usage

 

Checking for user data on login:

$result = $this->Authentication->getResult();
if ($result->isValid()) {

            //debug($result->getData()->user_type);exit;

            if($result->getData()->user_type <> 'super' && $result->getData()->user_type <> 'admin') {
                $this->Flash->error(__('You do not have access to these features.'));
                $this->Authentication->logout();
            }

            if ($result->getData()->locked) {
                $this->Authentication->logout();
                $this->Flash->error(__('You are not allowed to login, please contact administrator'));

            } else {
                // redirect to /articles after login success
                $redirect = $this->request->getQuery('redirect', [
                    'controller' => 'Users',
                    'action' => 'dashboard',
                ]);

                return $this->redirect($redirect);
            }
        }
        // display error if user submitted and authentication failed
        if ($this->request->is('post') && !$result->isValid()) {
            $this->Flash->error(__('Invalid email or password'));
        }

Most of this info is from this page in the cookbook: https://book.cakephp.org/4/en/tutorials-and-examples/blog-auth-example/auth.html

Tutorial:

https://codethepixel.com/cakephp/cakephp-4-authentication-authentication-plugin

Adding authentication to the app controller:

composer require cakephp/authentication:^2.0

Bootstrap the method in Application.php

// in src/Application.php in the bootstrap() method.
$this->addPlugin('Authentication');

Add Password Hashing in the User Model:

// src/Model/Entity/User.php
namespace App\\Model\\Entity;

use Cake\\Auth\\DefaultPasswordHasher;
use Cake\\ORM\\Entity;

class User extends Entity
{
    // Make all fields mass assignable except for primary key field "id".
protected $_accessible = [
        '*' =>true,
        'id' =>false];

    // ...

protected function _setPassword($password) {
				if (strlen($password) > 0) {
					return (new DefaultPasswordHasher)->hash($password);
        }
    }

    // ...
}

Imports - Application.php

// In src/Application.php add the following imports
use Authentication\\AuthenticationService;
use Authentication\\AuthenticationServiceInterface;
use Authentication\\AuthenticationServiceProviderInterface;
use Authentication\\Middleware\\AuthenticationMiddleware;
use Cake\\Routing\\Router;
use Psr\\Http\\Message\\ServerRequestInterface;

Implement the Authentication Interface in the Application Class - Application.php

// in src/Application.php
class Application extends BaseApplication
implements AuthenticationServiceProviderInterface
{

Add the Middleware to Application.php

// src/Application.php
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
    $middlewareQueue
        // ... other middleware added before
        ->add(new RoutingMiddleware($this))
        // add Authentication after RoutingMiddleware
        ->add(new AuthenticationMiddleware($this));

		return $middlewareQueue;
}

public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
    {
        $all=  explode('/',$_SERVER['REQUEST_URI']);
    //        echo ;exit
        $authenticationService = new AuthenticationService([
            'unauthenticatedRedirect' => $request->getAttribute('webroot').'admin/users/login',
            'queryParam' => 'redirect',
        ]);

        // Load identifiers, ensure we check email and password fields
        $authenticationService->loadIdentifier('Authentication.Password', [
            'fields' => [
                'username' => 'email',
                'password' => 'password',
            ]
        ]);

        // Load the authenticators, you want session first
        $authenticationService->loadAuthenticator('Authentication.Session');
        // Configure form data check to pick email and password
        $authenticationService->loadAuthenticator('Authentication.Form', [
            'fields' => [
                'username' => 'email',
                'password' => 'password',
            ],
            'loginUrl' => Router::url('/admin/users/login'),
        ]);

        return $authenticationService;
    }

Load the Component - AppController.php

// src/Controller/AppController.php
publicfunction initialize(): void
{
parent::initialize();
    $this->loadComponent('RequestHandler');
    $this->loadComponent('Flash');

    // Add this line to check authentication result and lock your site
    $this->loadComponent('Authentication.Authentication');
publicfunction beforeFilter(\\Cake\\Event\\EventInterface $event)
{
		parent::beforeFilter($event);
    // Configure the login action to not require authentication, preventing
    // the infinite redirect loop issue
    $this->Authentication->addUnauthenticatedActions(['login']);
}

Share this Post