Cakephp/authentication:^3.0 There are accounts with the same user information, and three fields are required to complete the verification

CREATE TABLE `emp` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `employee_num` varchar(255) DEFAULT NULL,
  `passwrod` varchar(255) DEFAULT NULL,
  `field_id` int DEFAULT NULL,
  `is_use_two_step_auth` int DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

New project

composer create-project --prefer-dist cakephp/app:~5.0 my_app_name

login.php

input: field_id
input: employee_num
input: passwrod

button URL: /users/login

1.How to configure getInstanceService?

public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
    {
        // Then pass it to the service configuration
        $service = new AuthenticationService();

        // Configuration common to both the API and web goes here.
        if ($request->getParam('prefix') == 'Api') {
            // Include API specific authenticators
        } else {

            $fields = [
                // 'field_id': I need three fields to enable authentication
                'username' => 'employee_num',
                'password' => 'password'
            ];

            $service->setConfig([
                'unauthenticatedRedirect' => Router::url('/users/login'),
                'queryParam' => 'redirect',
            ]);
            

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

            // Load the authenticators, you want session first
            $service->loadAuthenticator('Authentication.Session');
            $service->loadAuthenticator('Authentication.Form', [
                'fields' => $fields,
                'loginUrl' => '/users/login'
            ]);

        }

        return $service;
    }

You need at least a custom PasswordIdentifier so that you can adjust the query to be an AND, not an OR

Currently it is configured by default, that you can pass down multiple fields and it will try all given fields by themselves, not a combination (what you want)

I’d highly recommend you watch my workshop where I go through the whole authentication process and how it works (difference between Authenticators and Identifiers) and then you should be able to create what you want.

2 Likes

Thank you very much for your answer。