CakePHP ApiTokenAuthenticator Plugin

{
“user”: {
“id”: 1,
“token”: “yourSecretTokenComingFromTheDatabase”
}
}

Than you can use this token to authenticate yourself for accessing urls what requires authentication. The token should be sent in a request header named Token (or what you set in your config/apiTokenAuthenticator.php file).

How does it work? When i set JWT Token it return user data but if i go with this plugin ApiTokenAuthenticator then i get nothing in response just error status show 401 authentication require for this action, why?

$token = ‘wvOgZIKAhku8K5sUXBVdz4NCs0tj0ahery8akPRJIDs5WyitXhcAg’;

$params = http_build_query([‘profile[first_name]’=>‘bar’]);

$options = stream_context_create([‘http’=>[
‘method’=>‘GET’,
‘header’=>“Content-Type: application/x-www-form-urlencoded\r\n”.'Authorization: Bearer '.$token,
‘content’=>$params
]]);

$auth = ‘http://localhost/skyweb/api/v1/usuaria/logout.json’;
$user = ‘http://localhost/skyweb/api/v1/users.json’;

$api = file_get_contents($user,false,$options);
print_r($api);

the above code send request to cakephp Application for fetch information on the token basis but it does not work but JWT token return everything on demand.

Application.php

The TokenAuthenticator provided by cakephp you have configured either allows the request to be authenticated via a GET parameter like so

https://localhost?token=mytoken

or via a HTTP authorization header like mentioned in the docs.

How you get that token to the client is up 2 you.

But I dont see any Token Identifier config in your example.

You can of course also use the JWT system which you have also configured.

But i feel that you are mixing up the simple Token Auth system with the JWT auth system.

The Token system is a rather “fixed” system where e.g. a user entry “admin” in the db has an api_key column with the value “myapikey”

So if you then do a request with
https://localhost/?token=myapikey
that request will automatically be “logged in” as admin. But only for requests with that GET parameter or the HTTP authorization header.

Now in a JWT based system you would rather have a “normal” login action in your controller.
The users sends a normal POST with username and password to that action but instead of getting a auth cookie you will then get a time restricted JWT token which needs to be set in each following request.
So JWT is like a dynamic api key generation mechanism if you want to see it that way.
This token can also be either set as GET parameter or the HTTP authorization header. See the JWT Authenticator docs for the default config.

this is my configuration for API’s with JWT Token And Simple database users table Token //application.php

$service->loadAuthenticator(‘Authentication.Jwt’, [
‘secretKey’ => file_get_contents(CONFIG . ‘jwt.pem’),
‘algorithm’ => ‘RS256’,
‘returnPayload’ => false
]);
$service->loadAuthenticator(‘Authentication.Form’, [
‘fields’ => $fields,
‘loginUrl’ => Router::url(‘/api/v1/usuaria/login.json’),
]);
//$service->loadAuthenticator(‘Authentication.Session’);

        $service->loadAuthenticator('Authentication.Token', [
            'queryParam' => 'token',
            'header' => 'Authorization',
            'tokenPrefix' => 'Token',
        ]);

        $service->loadIdentifier('Authentication.JwtSubject', ['fields' => $fields, 'resolver' => ['className' => 'Authentication.Orm'], 'tokenField' => 'userkeyid']);

        $service->loadIdentifier('Authentication.Password', [
            'fields' => $fields,
            'resolver' => [
                'className' => 'Authentication.Orm',
                'finder' => 'authenticatedUser' // <<< there it goes
            ]
        ]);
        return $service;

the above code working fine for Jwt token, please check below code

$token = ‘eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJteWFwcCIsInN1YiI6ODA2NTQ5MDksImV4cCI6MTY4OTc3NjcyMX0.cW2vqOm-2BDOFLAgOJ9pdWlNKcIBNSHJR1DWakPdDA0JDp-_604JCobNjsiQy5XHaVo3R9ba6Vb5hXpJtAvvR-V-iMjrewRXEmUcvDs4tWMAnaHslGjQTLAvPJGhc6GFHPSDK2cnTe0S2-ufA6iyNIwaTA_rj6xzuCeWNlQ7SSQ’;

$params = http_build_query([‘profile[first_name]’=>‘bheem’]);

$options = stream_context_create([‘http’=>[
‘method’=>‘GET’,
‘header’=>“Content-Type: application/x-www-form-urlencoded\r\n”.'Authorization: Bearer '.$token,
‘content’=>$params
]]);

$auth = ‘http://localhost/skyweb/api/v1/usuaria/logout.json’;
$user = ‘http://localhost/skyweb/api/v1/users.json’;

$api = file_get_contents($user,false,$options);
print_r($api);

the above code run in different system not in cakephp… cakephp just service provider application when client machine call Cakephp Apis then Cakephp return data… but need to token for accessing information so Jwt token works fine but I want to fetch data with both tokens like Simple Token and Jwt Token. i am using this plugin for simple token:-

  • queryParam: Name of the query parameter. Configure it if you want to get the token from the query parameters.
  • header: Name of the header. Configure it if you want to get the token from the header.
  • tokenPrefix: The optional token prefix.

I have been following these steps but does not work.

‘header’=>“Content-Type: application/x-www-form-urlencoded\r\n”.'Authorization: Bearer '.$token,

it return 401 error so it means token does get cakephp side. then I try with like this https://example.com/api/v1/users.json?token=ldjlajsdljlajsdalkjdla even this is not work for me.

Just tell me how can i send token into Authorization Header. I do not want to use query parameter, better way is send in header Authorization.

Not really a CakePHP specific question but here we go:

I would highly recommend you take a look at https://www.postman.com/

Its a free tool to build HTTP requests in a nice GUI. It also can generate the Code for you.


So I have a working example in my local environment with the following config:

        $service->loadAuthenticator('Authentication.Token', [
            'header' => 'Authorization',
            'tokenPrefix' => 'SomethingStupid'
        ]);
        $service->loadIdentifier('Authentication.Token');

Then my users table has a column token because its the default inside the TokenIdentifier

Finally I can do a request with the Authorization header (generated by Postman) like so:

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'http://localhost:8765',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array(
    'Accept: application/json',
    'Authorization: SomethingStupid test',
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

As you can see i used the SomethingStupid prefix here just to be 100% clear where it is coming from and where it is connected (see loadAuthenticator above)

Which with a Controller like this (connected to the / route of course)

class ProductsController extends AppController
{
    public function viewClasses(): array
    {
        return [JsonView::class];
    }

    public function index()
    {
        $this->Authorization->skipAuthorization();
        $result = [
            'loggedIn' => true,
            'user' => $this->Authentication->getIdentity()->getOriginalData()
        ];
        $this->set(compact('result'));
        $this->viewBuilder()->setOption('serialize', ['result']);
    }
}

Will return this

{
    "result": {
        "loggedIn": true,
        "user": {
            "id": 2,
            "email": "info@pfeiferkevin.at",
            "first_name": "Kevin",
            "last_name": "Pfeifer",
            "locale": "de",
            "created": "2022-09-25T11:21:47+00:00",
            "modified": "2022-09-25T11:21:47+00:00"
        }
    }
}

hi @KevinPfeifer but i already check all whatever you mention above, POST MAN. yes l already checked This request with Postman and set Api token into header Authentication and it does the same thing as i mention Just JWT token working fine but database token does detected by cakephp. I think I have to do some manual work here for simple token for Authentication. My All code working fine @KevinPfeifer even Api’s too
Thanks for reply Bro