Cakephp 3.x ADmad/JwtAuth doesn't work

2019-08-15 02:41发布

问题:

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" : "fakeemail@gmail.com",
  "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?