1
votes

Currently I'm working with cakephp 3.1 to develop a restful API for an android app. I've been trying to use the ADmad/JwtAuth.Jwt component but I can't make it work, and I dont know why. I've followed this tutorial without using the CRUD component.This is my code:

AppController.php

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

    $this->loadComponent('RequestHandler');
    $this->loadComponent('Auth', [
       'storage' => 'Memory',
       'authenticate' => [
       'Form'=> ['fields' => ['username' => 'email', 'password' => 'password']],
       'ADmad/JwtAuth.Jwt' => [
           'parameter' => '_token',
           'userModel' => 'Users',
           'fields' => [
               'id' => 'id'
           ]
        ]
   ]
   ]);

   }

UserContoller.php

    use App\Controller\Api\AppController;
    use Cake\Network\Exception\UnauthorizedException;
    use Cake\Utility\Security;
    use Cake\Event\Event;


    class UsersController extends AppController
    {

     public function initialize()
     {
        parent::initialize();
         $this->Auth->allow(['ea']);
     }

    public function ea()
    {
      $user = $this->Auth->identify();
      if (!$user) {
        throw new UnauthorizedException('Invalid username or password');
      }

      $this->set([
        'success' => true,
        'data' => [
            'token' => $token = \JWT::encode([
                'id' => $user['id'],
                'exp' =>  time() + 604800
            ],
            Security::salt())
        ],
        '_serialize' => ['success', 'data']
      ]);
   }

I use the function ea() as a test, to see if it works. If I set $user instead of token in the data array it displays the user info with no problem and the message success : true, but when I try to use the jwt::encode() function it replies an error 500.

I have installed the latest version of ADmad/JwtAuth.Jwt (composer info command says dev-master 550c630).In bootstrap.php I've added the line Plugin::load('ADmad/JwtAuth');

Im new to cakephp, so it can be a silly mistake. I've spent more than a week trying to fix it myself, but I run out of ideas. Any help would be appreciated.

PS: I use postman client. The http post request is

{ "email" : "[email protected]",
  "password" : "pass"
}

UPDATE 1

I fixed my previous code, but now I have problems authenticating. This is how it looks right now

AppController

class AppController extends Controller{   
public function initialize(){   
   parent::initialize();
   $this->loadComponent('RequestHandler');
   $this->loadComponent('Auth', [
      'authenticate', [
          'ADmad/JwtAuth.Jwt' => [
           'storage' => 'Memory',
           'userModel' => 'Users',
           'fields' => [
               'username' => 'id'
           ],

           'parameter' => '_token',

           // Boolean indicating whether the "sub" claim of JWT payload
           // should be used to query the Users model and get user info.
           // If set to `false` JWT's payload is directly returned.
           'queryDatasource' =>true,
       ]
   ],
   'unauthorizedRedirect' => false,
   'checkAuthIn' => 'Controller.initialize',
   ]);
   }

UserController

 class UsersController extends AppController{

        public function initialize(){
            parent::initialize();
            $this->Auth->allow([ 'token','add']);
        }

        public function token(){
         $email = $this->request->data('email');
         $pwd = $this->request->data('password');
         $user = $this->Users->find()->where(['email' => $email])->first();
         $token=null;
         $success=false;

           if($user != null &&  (new DefaultPasswordHasher)->check($pwd, $user['password'])){
             $token = JWT::encode([
                      'id' => $user['id'],
                      'sub' => $user['id']
                     ],Security::salt());
             $succes=true;


           }
           $this->set([
                'success' => $success,
                'data' => [
                    'token' =>  $token
                ],
                '_serialize' => ['success', 'data']
            ]);
        }

Function token() works fine. If I allow the index() function in the initialize() function of UserController it works fine too, but if I dont allow it and I try to call it from a http request it gives me this response:

 {
  "message": "A route matching \"array (\n  'controller' => 'Users',\n  'action' => 'login',\n  'plugin' => NULL,\n  'prefix' => 'api',\n  '_ext' => NULL,\n)\" could not be found.",
  "url": "array (\n  'controller' => 'Users',\n  'action' => 'login',\n  'plugin' => NULL,\n  'prefix' => 'api',\n  '_ext' => NULL,\n)",
  "code": 404,
  "trace": [
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Routing/Router.php",
      "line": 617,
      "function": "match",
      "class": "Cake\Routing\RouteCollection",
      "type": "->",
      "args": [
        {
          "controller": "Users",
          "action": "login",
          "plugin": null,
          "prefix": "api",
          "_ext": null
        },
        {
          "_base": "/deportes",
          "_port": "80",
          "_scheme": "http",
          "_host": "localhost",
          "params": {
            "plugin": null,
            "controller": "Users",
            "action": "index",
            "_ext": null,
            "pass": [],
            "_method": "GET",
            "prefix": "api"
          }
        }
      ]
    },
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Routing/Router.php",
      "line": 730,
      "function": "url",
      "class": "Cake\Routing\Router",
      "type": "::",
      "args": [
        {
          "controller": "Users",
          "action": "login",
          "plugin": null
        }
      ]
    },
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Controller/Component/AuthComponent.php",
      "line": 400,
      "function": "normalize",
      "class": "Cake\Routing\Router",
      "type": "::",
      "args": [
        {
          "controller": "Users",
          "action": "login",
          "plugin": null
        }
      ]
    },
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Controller/Component/AuthComponent.php",
      "line": 290,
      "function": "_isLoginAction",
      "class": "Cake\Controller\Component\AuthComponent",
      "type": "->",
      "args": [
        {
          "name": "Users",
          "helpers": [],
          "request": {
            "params": {
              "plugin": null,
              "controller": "Users",
              "action": "index",
              "_ext": null,
              "pass": [],
              "_method": "GET",
              "prefix": "api",
              "isAjax": false
            },
            "data": [],
            "query": [],
            "cookies": {
              "CAKEPHP": "vaj518odrn96id8asjhpluob00"
            },
            "url": "api/users",
            "base": "/deportes",
            "webroot": "/deportes/",
            "here": "/deportes/api/users",
            "trustProxy": false
          },
          "response": {},
          "paginate": [],
          "autoRender": true,
          "components": [],
          "View": null,
          "plugin": null,
          "passedArgs": [],
          "modelClass": "Users",
          "viewClass": null,
          "viewVars": [],
          "RequestHandler": {
            "enabled": true,
            "response": {},
            "ext": null,
            "request": {
              "params": {
                "plugin": null,
                "controller": "Users",
                "action": "index",
                "_ext": null,
                "pass": [],
                "_method": "GET",
                "prefix": "api",
                "isAjax": false
              },
              "data": [],
              "query": [],
              "cookies": {
                "CAKEPHP": "vaj518odrn96id8asjhpluob00"
              },
              "url": "api/users",
              "base": "/deportes",
              "webroot": "/deportes/",
              "here": "/deportes/api/users",
              "trustProxy": false
            },
            "components": []
          },
          "Auth": {
            "components": [
              "RequestHandler",
              "Flash"
            ],
            "allowedActions": [
              "token",
              "add"
            ],
            "request": {
              "params": {
                "plugin": null,
                "controller": "Users",
                "action": "index",
                "_ext": null,
                "pass": [],
                "_method": "GET",
                "prefix": "api",
                "isAjax": false
              },
              "data": [],
              "query": [],
              "cookies": {
                "CAKEPHP": "vaj518odrn96id8asjhpluob00"
              },
              "url": "api/users",
              "base": "/deportes",
              "webroot": "/deportes/",
              "here": "/deportes/api/users",
              "trustProxy": false
            },
            "response": {},
            "session": {}
          }
        }
      ]
    },
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Event/EventManager.php",
      "line": 385,
      "function": "authCheck",
      "class": "Cake\Controller\Component\AuthComponent",
      "type": "->",
      "args": [
        {
          "data": null,
          "result": null
        }
      ]
    },
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Event/EventManager.php",
      "line": 355,
      "function": "_callListener",
      "class": "Cake\Event\EventManager",
      "type": "->",
      "args": [
        [
          {
            "components": [
              "RequestHandler",
              "Flash"
            ],
            "allowedActions": [
              "token",
              "add"
            ],
            "request": {
              "params": {
                "plugin": null,
                "controller": "Users",
                "action": "index",
                "_ext": null,
                "pass": [],
                "_method": "GET",
                "prefix": "api",
                "isAjax": false
              },
              "data": [],
              "query": [],
              "cookies": {
                "CAKEPHP": "vaj518odrn96id8asjhpluob00"
              },
              "url": "api/users",
              "base": "/deportes",
              "webroot": "/deportes/",
              "here": "/deportes/api/users",
              "trustProxy": false
            },
            "response": {},
            "session": {}
          },
          "authCheck"
        ],
        {
          "data": null,
          "result": null
        }
      ]
    },
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Event/EventDispatcherTrait.php",
      "line": 78,
      "function": "dispatch",
      "class": "Cake\Event\EventManager",
      "type": "->",
      "args": [
        {
          "data": null,
          "result": null
        }
      ]
    },
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Controller/Controller.php",
      "line": 491,
      "function": "dispatchEvent",
      "class": "Cake\Controller\Controller",
      "type": "->",
      "args": [
        "Controller.initialize"
      ]
    },
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Routing/Dispatcher.php",
      "line": 109,
      "function": "startupProcess",
      "class": "Cake\Controller\Controller",
      "type": "->",
      "args": []
    },
    {
      "file": "/var/www/html/deportes/vendor/cakephp/cakephp/src/Routing/Dispatcher.php",
      "line": 87,
      "function": "_invoke",
      "class": "Cake\Routing\Dispatcher",
      "type": "->",
      "args": [
        {
          "name": "Users",
          "helpers": [],
          "request": {
            "params": {
              "plugin": null,
              "controller": "Users",
              "action": "index",
              "_ext": null,
              "pass": [],
              "_method": "GET",
              "prefix": "api",
              "isAjax": false
            },
            "data": [],
            "query": [],
            "cookies": {
              "CAKEPHP": "vaj518odrn96id8asjhpluob00"
            },
            "url": "api/users",
            "base": "/deportes",
            "webroot": "/deportes/",
            "here": "/deportes/api/users",
            "trustProxy": false
          },
          "response": {},
          "paginate": [],
          "autoRender": true,
          "components": [],
          "View": null,
          "plugin": null,
          "passedArgs": [],
          "modelClass": "Users",
          "viewClass": null,
          "viewVars": [],
          "RequestHandler": {
            "enabled": true,
            "response": {},
            "ext": null,
            "request": {
              "params": {
                "plugin": null,
                "controller": "Users",
                "action": "index",
                "_ext": null,
                "pass": [],
                "_method": "GET",
                "prefix": "api",
                "isAjax": false
              },
              "data": [],
              "query": [],
              "cookies": {
                "CAKEPHP": "vaj518odrn96id8asjhpluob00"
              },
              "url": "api/users",
              "base": "/deportes",
              "webroot": "/deportes/",
              "here": "/deportes/api/users",
              "trustProxy": false
            },
            "components": []
          },
          "Auth": {
            "components": [
              "RequestHandler",
              "Flash"
            ],
            "allowedActions": [
              "token",
              "add"
            ],
            "request": {
              "params": {
                "plugin": null,
                "controller": "Users",
                "action": "index",
                "_ext": null,
                "pass": [],
                "_method": "GET",
                "prefix": "api",
                "isAjax": false
              },
              "data": [],
              "query": [],
              "cookies": {
                "CAKEPHP": "vaj518odrn96id8asjhpluob00"
              },
              "url": "api/users",
              "base": "/deportes",
              "webroot": "/deportes/",
              "here": "/deportes/api/users",
              "trustProxy": false
            },
            "response": {},
            "session": {}
          }
        }
      ]
    },
    {
      "file": "/var/www/html/deportes/webroot/index.php",
      "line": 37,
      "function": "dispatch",
      "class": "Cake\Routing\Dispatcher",
      "type": "->",
      "args": [
        {
          "params": {
            "plugin": null,
            "controller": "Users",
            "action": "index",
            "_ext": null,
            "pass": [],
            "_method": "GET",
            "prefix": "api",
            "isAjax": false
          },
          "data": [],
          "query": [],
          "cookies": {
            "CAKEPHP": "vaj518odrn96id8asjhpluob00"
          },
          "url": "api/users",
          "base": "/deportes",
          "webroot": "/deportes/",
          "here": "/deportes/api/users",
          "trustProxy": false
        },
        {}
      ]
    }
  ]
}  

Image from postman with the request

As you can see in the image above I use the Authorization header. Any ideas?

Quoting the README of master branch: "For an end to end usage example check out this blog post by Bravo Kernel. That tutorial is for v1.0 of this plugin so update code examples accordingly." - ADmad
Thank you for your answer, but my problem is that I dont know which code I have to update. I've changed the loadComponent function in AppController with the setup of the README file but still prompting 500 error, but this time even without calling the encode function. If there is any code implementing this version I coudln't find it. Is there any file that explains which code I have to update? - ChocoboGordo
The README of the plugin provides all relevant info. If you are getting some error provide exact details. Me or anyone else can't guess what error you are having. - ADmad