# Token authentication on CakePHP 4 with plugin

**URL:** <https://discourse.cakephp.org/t/token-authentication-on-cakephp-4-with-plugin/11453>\
**Category:** Need Help\
**Created:** [August 20, 2023, 4:04pm UTC](https://discourse.cakephp.org/t/token-authentication-on-cakephp-4-with-plugin/11453 "2023-08-20T16:04:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dcoturel](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/dcoturel/32/1468_2.png) [@dcoturel](https://discourse.cakephp.org/u/dcoturel)\
**Post date:** [August 20, 2023, 4:04pm UTC](https://discourse.cakephp.org/t/token-authentication-on-cakephp-4-with-plugin/11453/1 "2023-08-20T16:04:48Z")

</div>

Hi everyone!

I’m developing an app with two authentication models. One is a forma authentication, wich acts properly. The other one is token authentication, because the app will publish an api. All of this made with the Authentication plugin.

So, I created a Tokens table, linked to the Users table vía foreign key (Tokens.user\_id). This table has a Token field, with hashing. This is the code:

```auto
<?php
declare(strict_types=1);

namespace App\Model\Entity;

use Cake\ORM\Entity;
use Authentication\PasswordHasher\DefaultPasswordHasher;
/**
 * Token Entity
 *
 * @property int $id
 * @property int $user_id
 * @property string $name
 * @property string $scope
 * @property \Cake\I18n\FrozenTime $created
 * @property \Cake\I18n\FrozenTime $modified
 * @property string $token
 * @property int $enabled
 */
class Token extends Entity
{
    /**
     * Fields that can be mass assigned using newEntity() or patchEntity().
     *
     * Note that when '*' is set to true, this allows all unspecified fields to
     * be mass assigned. For security purposes, it is advised to set '*' to false
     * (or remove it), and explicitly make individual fields accessible as needed.
     *
     * @var array<string, bool>
     */
    protected $_accessible = [
        'user_id' => true,
        'name' => true,
        'scope' => true,
        'created' => true,
        'modified' => true,
        'token' => true,
        'enabled' => true,
    ];

    /**
     * Fields that are excluded from JSON versions of the entity.
     *
     * @var array<string>
     */
    protected $_hidden = [
        'token',
    ];
    
    protected function _setToken(string $token)
    {
        $hasher = new DefaultPasswordHasher();
        return $hasher->hash($token);
    }
    
    
}

```

Then, I added this to the Application class:

```auto
if ($request->is('json')) {
            $authenticationService = new AuthenticationService([
                'queryParam' => 'redirect',
            ]);

            $authenticationService->loadIdentifier('Authentication.Token', [
                'tokenField' => 'token',
                'dataField' => 'token',
                'resolver' => [
                    'className' => 'Authentication.Orm',
                    'userModel' => 'Tokens',
                    'finder' => 'all',
                ],
            ]);
            
            $authenticationService->loadAuthenticator('Authentication.Token', [
                'queryParam' => 'token',
                'header' => 'Authorization',
                'tokenPrefix' => 'Token',
            ]);
        }

```

The thing is, this method of authentication works perfectly if I don’t hash the token in the request. I can’t find how to configure the identifier in order to hash the request data correctly. Has anyone any working example of this? I went through the documentation several times.

Saludos,

---

<div class="post-metadata">

**Author:** ![Mentis](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/mentis/32/994_2.png) [@Mentis](https://discourse.cakephp.org/u/Mentis)\
**Post date:** [August 21, 2023, 5:28pm UTC](https://discourse.cakephp.org/t/token-authentication-on-cakephp-4-with-plugin/11453/2 "2023-08-21T17:28:24Z")

</div>

Edit: Have you looked into the [`hashAlgorithm` option](https://book.cakephp.org/authentication/2/en/identifiers.html#token) you can pass to the `TokenIdentifier`?

```php
$authenticationService->loadIdentifier('Authentication.Token', [
    'hashAlgorithm' => ' __HASH_ALGORITHM_HERE__',
    'tokenField' => 'token',
    'dataField' => 'token',
    'resolver' => [
        'className' => 'Authentication.Orm',
        'userModel' => 'Tokens',
        'finder' => 'all',
    ],
]);

```

* * *

The `TokenIdentifier` class that comes with the `AuthenticationPlugin` is comparing the database value against the value provided in the request, without hashing it.

You can either implement your own `TokenIdentifier`, by extending CakePHP’s and overwrite the `identify` method, or you can define your own finder method.

 ![image](https://canada1.discourse-cdn.com/flex029/uploads/cakephp/original/2X/1/16e0a508239c5d75a56bd69609771930e9662dbb.png)

---

<div class="post-metadata">

**Author:** ![dcoturel](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/dcoturel/32/1468_2.png) [@dcoturel](https://discourse.cakephp.org/u/dcoturel)\
**Post date:** [August 28, 2023, 1:16pm UTC](https://discourse.cakephp.org/t/token-authentication-on-cakephp-4-with-plugin/11453/3 "2023-08-28T13:16:41Z")

</div>

Hi Mentis,

Thanks for your answer. I have observed the existence of the hashAlgorithm option, but I don’t know which value I should write there that corresponds with the default password hasher.

I haven’t found that in any of the doc or source code for the plugin. Do you know the values accepted by that option?

Saludos,
