Cakephp 3.x ADmad/JwtAuth丢失路由异常

Cakephp 3.x ADmad/JwtAuth丢失路由异常,php,json,cakephp,cakephp-3.0,jwt,Php,Json,Cakephp,Cakephp 3.0,Jwt,老问题,但我的错误与@ChocoboGordo()完全相同。 当我尝试在CakePHP Rest API中使用JWT(不使用CRUD插件)时,我得到一个MissingRouteException,因为它找不到登录路径(请参见下面的响应)。 有什么想法吗 这是我的代码: App\Controller\Api\AppController public function initialize() { parent::initialize(); $this->loadCompone

老问题,但我的错误与@ChocoboGordo()完全相同。 当我尝试在CakePHP Rest API中使用JWT(不使用CRUD插件)时,我得到一个MissingRouteException,因为它找不到登录路径(请参见下面的响应)。 有什么想法吗

这是我的代码: App\Controller\Api\AppController

public function initialize()
{
    parent::initialize();
    $this->loadComponent('RequestHandler');

    $this->loadComponent('Auth', [
        'storage' => 'Memory',
        'loginAction' => [
            'prefix' => 'api',
            'controller' => 'Usuario',
            'action' => 'login',
            'plugin' => false
        ],
        'authenticate' => [
            'Form' => [
                'userModel' => 'Usuario',
                'scope' => ['Usuario.Activo' => 1],
                'fields' => [
                    'username' => 'DNI',
                    'password' => 'Clave'
                ],
            ],
            'ADmad/JwtAuth.Jwt' => [
                'parameter' => 'token',
                'userModel' => 'Usuario',
                'scope' => ['Usuario.Activo' => 1],
                'fields' => [
                    'username' => 'DNI',
                    'password' => 'Clave'
                ],
                'queryDatasource' => true
            ]
        ],
        'unauthorizedRedirect' => false,
        'checkAuthIn' => 'Controller.initialize'
    ]);
}
config\routes.php:

Router::prefix('api', function ($routes) {
$routes->extensions(['json']);
...
$routes->resources('Usuario', [
    'map' => [
        'login' => [
            'controller' => 'Usuario',
            'action' => 'login'
        ]
    ]
]);
...
});
public function initialize()
{
    parent::initialize();
    $this->Auth->allow(['add', 'login']);
}
...
public function login() {
    if ($this->request->is(['post'])) {
        $this->response->header('Access-Control-Allow-Origin', '*');

        $postParams = $this->request->input('json_decode', true) ;
        if (!isset($postParams['DNI']) || !isset($postParams['Clave']))
            throw new BadRequestException();

        $_POST['DNI'] = $postParams['DNI'];
        $_POST['Clave'] = $postParams['Clave'];

        $user = $this->Auth->identify();
        if (!$user) {
            throw new UnauthorizedException('Auth error');
        }

        $this->set(array(
            'message' => 'Login Ok',
            'token' => JWT::encode([
                'sub' => $user['DNI'],
                'exp' =>  time() + 604800
            ],
            Security::salt()),
            '_serialize' => array('message', 'token')
        ));

        return;
    }

    throw new BadRequestException();
}
Error: [Cake\Routing\Exception\MissingRouteException] A route matching    'prefix' => 'api',
  'controller' => 'Usuario',
  'action' => 'login',
  'plugin' => NULL,
  '_ext' => NULL,
)" could not be found.
Exception Attributes: array (
  'url' => 'array (
  \'prefix\' => \'api\',
  \'controller\' => \'Usuario\',
  \'action\' => \'login\',
  \'plugin\' => NULL,
  \'_ext\' => NULL,
)',
  'context' => 
  array (
    '_base' => '/registro-api',
    '_port' => '80',
    '_scheme' => 'http',
    '_host' => 'localhost',
    'params' => 
    array (
      'pass' => 
      array (
      ),
      'controller' => 'Usuario',
      'action' => 'index',
      '_method' => 'GET',
      'prefix' => 'api',
      'plugin' => NULL,
      '_matchedRoute' => '/api/usuario',
      '_ext' => NULL,
    ),
  ),
)
Request URL: /api/usuario
Controller\Api\UsuarioController:

Router::prefix('api', function ($routes) {
$routes->extensions(['json']);
...
$routes->resources('Usuario', [
    'map' => [
        'login' => [
            'controller' => 'Usuario',
            'action' => 'login'
        ]
    ]
]);
...
});
public function initialize()
{
    parent::initialize();
    $this->Auth->allow(['add', 'login']);
}
...
public function login() {
    if ($this->request->is(['post'])) {
        $this->response->header('Access-Control-Allow-Origin', '*');

        $postParams = $this->request->input('json_decode', true) ;
        if (!isset($postParams['DNI']) || !isset($postParams['Clave']))
            throw new BadRequestException();

        $_POST['DNI'] = $postParams['DNI'];
        $_POST['Clave'] = $postParams['Clave'];

        $user = $this->Auth->identify();
        if (!$user) {
            throw new UnauthorizedException('Auth error');
        }

        $this->set(array(
            'message' => 'Login Ok',
            'token' => JWT::encode([
                'sub' => $user['DNI'],
                'exp' =>  time() + 604800
            ],
            Security::salt()),
            '_serialize' => array('message', 'token')
        ));

        return;
    }

    throw new BadRequestException();
}
Error: [Cake\Routing\Exception\MissingRouteException] A route matching    'prefix' => 'api',
  'controller' => 'Usuario',
  'action' => 'login',
  'plugin' => NULL,
  '_ext' => NULL,
)" could not be found.
Exception Attributes: array (
  'url' => 'array (
  \'prefix\' => \'api\',
  \'controller\' => \'Usuario\',
  \'action\' => \'login\',
  \'plugin\' => NULL,
  \'_ext\' => NULL,
)',
  'context' => 
  array (
    '_base' => '/registro-api',
    '_port' => '80',
    '_scheme' => 'http',
    '_host' => 'localhost',
    'params' => 
    array (
      'pass' => 
      array (
      ),
      'controller' => 'Usuario',
      'action' => 'index',
      '_method' => 'GET',
      'prefix' => 'api',
      'plugin' => NULL,
      '_matchedRoute' => '/api/usuario',
      '_ext' => NULL,
    ),
  ),
)
Request URL: /api/usuario
当我调用登录时,它会工作并正确地给我令牌。但是,当我尝试调用另一个操作(包括带有Bearer+令牌的自动化头)时,会显示以下错误:

响应:

Router::prefix('api', function ($routes) {
$routes->extensions(['json']);
...
$routes->resources('Usuario', [
    'map' => [
        'login' => [
            'controller' => 'Usuario',
            'action' => 'login'
        ]
    ]
]);
...
});
public function initialize()
{
    parent::initialize();
    $this->Auth->allow(['add', 'login']);
}
...
public function login() {
    if ($this->request->is(['post'])) {
        $this->response->header('Access-Control-Allow-Origin', '*');

        $postParams = $this->request->input('json_decode', true) ;
        if (!isset($postParams['DNI']) || !isset($postParams['Clave']))
            throw new BadRequestException();

        $_POST['DNI'] = $postParams['DNI'];
        $_POST['Clave'] = $postParams['Clave'];

        $user = $this->Auth->identify();
        if (!$user) {
            throw new UnauthorizedException('Auth error');
        }

        $this->set(array(
            'message' => 'Login Ok',
            'token' => JWT::encode([
                'sub' => $user['DNI'],
                'exp' =>  time() + 604800
            ],
            Security::salt()),
            '_serialize' => array('message', 'token')
        ));

        return;
    }

    throw new BadRequestException();
}
Error: [Cake\Routing\Exception\MissingRouteException] A route matching    'prefix' => 'api',
  'controller' => 'Usuario',
  'action' => 'login',
  'plugin' => NULL,
  '_ext' => NULL,
)" could not be found.
Exception Attributes: array (
  'url' => 'array (
  \'prefix\' => \'api\',
  \'controller\' => \'Usuario\',
  \'action\' => \'login\',
  \'plugin\' => NULL,
  \'_ext\' => NULL,
)',
  'context' => 
  array (
    '_base' => '/registro-api',
    '_port' => '80',
    '_scheme' => 'http',
    '_host' => 'localhost',
    'params' => 
    array (
      'pass' => 
      array (
      ),
      'controller' => 'Usuario',
      'action' => 'index',
      '_method' => 'GET',
      'prefix' => 'api',
      'plugin' => NULL,
      '_matchedRoute' => '/api/usuario',
      '_ext' => NULL,
    ),
  ),
)
Request URL: /api/usuario
我不使用CRUD插件。
请帮忙

正如错误消息所说,该URL数组没有匹配的路由。每当遇到该错误时,请查看应用程序中连接了哪些路由(
bin/cake routes
),并检查错误堆栈跟踪以确定问题调用的来源。在这种情况下,可以肯定地说它源于auth组件,该组件使用
loginAction
URL数组

资源路由是特定于HTTP方法的 资源路由定义匹配它们所需的HTTP请求方法。生成URL时,您必须通过
\u method
选项键提供相应的方法,您的
登录操作
配置缺失,因此会出现错误

自定义资源端点的默认方法是
GET
,因此您必须添加

'_method' => 'GET'
到您的
登录操作
配置。但是,该方法与您的登录操作代码冲突,这需要
POST
(您可以使用
$this->request->allowMethod('POST')
顺便说一句,而不是手动测试和引发异常)。因此,您必须更改自定义资源端点定义以映射到
POST
方法:

$routes->resources('Usuario', [
    'map' => [
        'login' => [
            'controller' => 'Usuario',
            'action' => 'login',
            'method' => 'POST' // <<<<
        ]
    ]
]);
附言 摆弄
$\u POST
超全局似乎没有太多意义。通常,应该避免在CakePHP中访问superglobals,因为它在某些时候很容易咬到您,特别是在测试环境中

不需要手动解析输入,如果您发送了正确的请求,那么请求处理程序组件应该处理该输入,即使用
.json
扩展名或正确的
Accept

另见

无论何时收到错误,请始终发布完整的错误,即包括完整的stacktrace(最好是从日志中以适当可读的方式复制),即使熟悉CakePHP的人可能会明显看到问题!另外,请始终提及您的确切CakePHP版本(供应商/CakePHP/CakePHP/version.txt中的最后一行))-谢谢!非常感谢**@ndm**!!这让我发疯,现在它工作得很好。