How to use CakePHP’s AuthComponent to log in with arbitrary data without using a password

Sep 5, 2020 PHP CakePHP auth cakephp3

Preface

Since I implemented login using AuthComponent without using a password, I wrote a memo It is implemented so that you can log in from data in multiple tables instead of just one table.

As an image As a package redelivery site It is an image that allows you to make a redelivery request with both a telephone number and a redelivery number.

Development environment

PHP 3.6 CakePHP 3.8

  • Notes AuthComponent has been deprecated since CakePHP 4.0.0 and has been replaced by the authorization and authentication plugins. Source: CakePHP Official (AuthComponent)

The first answer

class AppController extends Controller
{

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


        $ this-> loadComponent ('RequestHandler', [
            'enableBeforeRedirect' => false,
        ]);
        $ this-> loadComponent ('Flash');

        // The login item is written in the login method of CustomersController
        $ this-> loadComponent ('Auth', [
            'authenticate', [
                'Form' => ['userModel' =>'Deliveries'],
                'fields' => [
                    'delivery_no' =>'delivery_no',
                    'user_phone' =>'user_phone',
                ],,
            // Where to log in
            'loginAction' => [
                'controller' =>'Deliveries',
                'action' =>'login'
            ],,
            // Redirect destination after login
            'loginRedirect' => [
                'controller' =>'Deliveries',
                'action' =>'list'
            ],,
            // Alert when opening the page after logging in even though you are not logged in
            'authError' => __ ('Please log in.')
        ]);
    }
}

Maybe I’m going to write an AppController using’userModel’ like this, but it doesn’t work. POSTing according to the record contents should not work.

Cause

protected function _findUser ($ username, $ password = null)
{
    $ result = $ this-> _query ($ username)-> first ();

    if ($ result === null) {
        // Waste time hashing the password, to prevent
        // timing side-channels. However, don't hash
        // null passwords as authentication systems
        // like digest auth don't use passwords
        // and hashing * could * create a timing side-channel.
        if ($ password! == null) {
            $ hasher = $ this-> passwordHasher ();
            $ hasher-> hash ($ password);
        }


        return false;
    }
..
..
..
}

Looking at the contents of AuthComponent, the second argument (?) Is made on the assumption that it is hashed, so even if you include unhashed data in the login contents, it will not work. I am. You can rewrite the description here or hash the referenced data, but I hate rewriting the core part of cakephp and it is only a risk to directly tamper with the database, so I will implement it as an alternative I will.

Main story

    / **
     * login --Login process
     *
     * /
    public function login ()
    {
        $ this-> autoRender = false;

        // POST
        if ($ this-> request-> is ('post')) {

            $ post_date = $ this-> request-> getData ();

            // Find what you want to log in based on the POSTed information
            $ login_user = $ this-> Deliveries-> find ()
                -> contain (['Deliveries'])
                -> where ([[
                    'Deliveries.delivery_no' => $ post_date ['delivery_no'],
                    'Customers.user_phone' => $ post_date ['user_phone']
                ])
                -> first ();

            // If there is search result data
            if (! empty ($ login_user)) {
                // Save user information in session
                $ this-> Auth-> setUser ($ login_user-> toArray ());
                return $ this-> redirect ($ this-> Auth-> redirectUrl ());
            } else {
                // Return to the original page
                return $ this-> redirect ($ this-> referer ());
            }
        }
    }
<? php
namespace App \ Controller;


use Cake \ Controller \ Controller;
use Cake \ Controller \ Component \ AuthComponent;
use Cake \ Event \ Event;
use Cake \ ORM \ TableRegistry;


/ **
* Application Controller
* /
class AppController extends Controller
{

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


        $ this-> loadComponent ('RequestHandler', [
            'enableBeforeRedirect' => false,
        ]);
        $ this-> loadComponent ('Flash');

        // The login item is written in the login method of CustomersController
        $ this-> loadComponent ('Auth', [
            // Where to log in
            'loginAction' => [
                'controller' =>'Deliveries',
                'action' =>'login'
            ],,
            // Redirect destination after login
            'loginRedirect' => [
                'controller' =>'Deliveries',
                'action' =>'list'
            ],,
            // Alert when opening the page after logging in even though you are not logged in
            'authError' => __ ('Please log in.')
        ]);
    }
}

All I did was search the database with SQL (find function) based on the POSTed content when logging in, and if found, just have it in the session. Deleted “authenticate” written in AppController because it is unnecessary.

Reference site

CakePHP official website (AuthComponent-manual user login) It’s important to read the formula. It’s hard to read, but it says it’s important.