Skip to content
CODE THE PIXEL
CakePHP

CakePHP 4 Log User Authentication Using Component

Asyraf Wahi Anuar Updated 3 min read

This tutorial will discuss how to create a user activities log using the CakePHP component. The basic activities that will be logged are the authentication method which includes the login and logout details.

This tutorial may be outdated

It was last reviewed 4 years ago. Some steps may differ in newer versions.

Tech stack

  • CakePHP 4.x

This tutorial will discuss how to create a user activities log using the CakePHP component. The basic activities that will be logged are the authentication method which includes the login and logout details. Technically, the logs will capture the authenticated user_id; action (login/logout); user agent; operating system; IP address; host; referrer; status and when the action is taken. According to CakePHP Book (2022), components are packages of logic that are shared between controllers. CakePHP comes with a fantastic set of core components you can use to aid in various common tasks. You can also create your own components. If you find yourself wanting to copy and paste things between controllers, you should consider creating your own component to contain the functionality. Creating components keeps controller code clean and allows you to reuse code between different controllers.

The Database Table

Create the database using the following schema:

PHP
/*
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id   | int(11)      | YES  |     | NULL    |                |
| action    | varchar(255) | YES  |     | NULL    |                |
| useragent | varchar(256) | YES  |     | NULL    |                |
| os        | varchar(255) | YES  |     | NULL    |                |
| ip        | varchar(50)  | YES  |     | NULL    |                |
| host      | varchar(255) | YES  |     | NULL    |                |
| referrer  | varchar(255) | NO   |     | NULL    |                |
| status    | int(1)       | YES  |     | 1       |                |
| created   | datetime     | YES  |     | NULL    |                |
| modified  | datetime     | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
*/
CREATE TABLE `user_logs` (
  `id` int(11) NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  `action` varchar(255) DEFAULT NULL,
  `useragent` varchar(256) DEFAULT NULL,
  `os` varchar(255) DEFAULT NULL,
  `ip` varchar(50) DEFAULT NULL,
  `host` varchar(255) DEFAULT NULL,
  `referrer` varchar(255) NOT NULL,
  `status` int(1) DEFAULT 1,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `user_logs`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `user_logs`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;

The UserLogs Components

You can bake the UserLogsComponent using the following command and it will generate the UserLogsComponent.php

Terminal
bin/cake bake component user_logs

or simply create the components file at ...\src\Controller\Component\UserLogsComponent.php and paste the following code. The public function userLoginActivity is used to capture the action details for login and userLogoutActivity will capture logout action details. For this example, I use CakePHP Authentication Plugin.

src/Controller/Component/UserLogsComponent.phpPHP
<?php
declare(strict_types=1);

namespace App\Controller\Component;

use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use Cake\ORM\Locator\LocatorAwareTrait;
use Cake\Http\ServerRequest;

class UserLogsComponent extends Component
{ 
    use LocatorAwareTrait;
    
    protected $_defaultConfig = [];

    public function userLoginActivity($user_id)
    {
        $request = new ServerRequest;
        $userLogTable = $this->getTableLocator()->get('UserLogs');
        $userlog = $userLogTable->newEmptyEntity();
        $userlog->user_id = $user_id;
        $userlog->ip = $request->clientIp();
        $userlog->action = 'Login';
        $userlog->useragent = $_SERVER['HTTP_USER_AGENT'];
        $userlog->os = php_uname('v');
        $userlog->host = gethostname();
        $userLogTable->save($userlog);
    }
    
    public function userLogoutActivity($user_id)
    {
        $request = new ServerRequest;
        $userLogTable = $this->getTableLocator()->get('UserLogs');
        $userlog = $userLogTable->newEmptyEntity();
        $userlog->user_id = $user_id;
        $userlog->ip = $request->clientIp();
        $userlog->action = 'Logout';
        $userlog->useragent = $_SERVER['HTTP_USER_AGENT'];
        $userlog->os = php_uname('v');
        $userlog->host = gethostname();
        $userlog->referrer = $_SERVER['HTTP_REFERER'];
        $userLogTable->save($userlog);
    }
}

Load UserLogs Component

In your User Controller, load the UserLogs component in the public function initialize as shown below:

PHP
public function initialize(): void
{
    parent::initialize();
    
    $this->loadComponent('UserLogs');
}

Add the following code to your login/logout method. Depending on your auth method, call the user_id to capture the authenticated user.

PHP
//login
$this->UserLogs->userLoginActivity($this->Authentication->getIdentity('id')->getIdentifier('id'));
//logout
$this->UserLogs->userLogoutActivity($this->Authentication->getIdentity('id')->getIdentifier('id'));

The following codes are examples of the UserLogs component applies in the login and logout method.

PHP
public function login()
{
    $this->request->allowMethod(['get', 'post']);
    $result = $this->Authentication->getResult();
    if ($result->isValid()) {
        $this->UserLogs->userLoginActivity($this->Authentication->getIdentity('id')->getIdentifier('id'));
        $redirect = $this->request->getQuery('redirect', ['prefix' => 'Admin', 'controller' => 'Dashboards', 'action' => 'index']);
        return $this->redirect($redirect);
    }
    if ($this->request->is('post') && !$result->isValid()) {
        $this->Flash->error(__('Invalid username or password'));
    }
}

public function logout()
{
    $result = $this->Authentication->getResult();
    if ($result->isValid()) {
        $this->UserLogs->userLogoutActivity($this->Authentication->getIdentity('id')->getIdentifier('id'));
        $this->Authentication->logout();
        return $this->redirect(['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'login']);
    }
}

As the codes are applied in your project, they will capture the details of the login and logout method. You can create the view for the user_logs table to browse the data. That's all. Happy coding.

Did this tutorial help?

196 readers found this helpful

Comments

No comments yet. Questions about this tutorial are welcome here: the answer helps the next reader too.

Leave a comment

Markdown works: `code`, ``` blocks, **bold**, links.

First comments are reviewed before they appear.

CakePHP

CakePHP 4 ActivityLogger plugin

Activity logging is one of the very useful features in web applications since it can provide a track of activities in the web content. CakePHP Activity Logger Plugin enables the developer or administrator to log the activities and changes to the web content.

3 min read

CakePHP

CakePHP 4 Auth Using CakeDC User Plugin

Authentication and authorization are critical components in the protection of online application content. They validate the user's identification and give access to the resources.

8 min read

CakePHP

CakePHP 4 Authentication Using Auth Component (Advance)

This tutorial will show how to create an authentication using the Auth component for CakePHP 4. It includes the process of password hashing, registration with email verification, multi-field username/email login, forgot password, reset password and status management.

10 min read