Cakephp 认证结果仅在无状态验证时无效

Cakephp authentication results invalid only on stateless verification

使用身份验证插件,我无法通过 json 验证我的凭据。我可以使用 Form、Jwt 和 Basic(用于测试它是否有效)。返回的错误是 'FAILURE_CREDENTIALS_INVALID'。这是示例代码 "simplified for brevity"

public function token()
{

    $result = $this->Authentication->getResult();
    if ($result->isValid()) {
        //new jwt token etc
        $message = true;
        $this->log($result->getStatus());

    }else{
        $message = false;
        $this->log($result->getStatus());

    }

    $this->set([
        'message' => $message,

    ]);

    $this->viewBuilder()->setOption('serialize', ['message']);

}

我的应用程序class有方法

public function getAuthenticationService(ServerRequestInterface $request) : AuthenticationServiceInterface
{

    $service = new AuthenticationService();

    $service->setConfig([
        'unauthenticatedRedirect' => '/users/login',
        'queryParam' => 'redirect',
    ]);


    $fields = [
        'username' => 'email',
        'password' => 'password'
    ];

    // Load the authenticators, you want session first
    $service->loadAuthenticator('Authentication.Session');
    $service->loadAuthenticator('Authentication.Form', [
        'fields' => $fields,
        'loginUrl' => '/users/login'
    ]);

    //Testing jwt
    $service->loadAuthenticator('Authentication.Jwt', [
        'secretKey' => Security::getSalt()]);

    // Load identifiers
    $service->loadIdentifier('Authentication.Password', compact('fields'));
    $service->loadIdentifier('Authentication.JwtSubject');

    return $service;
}

如果我传入 jwt,该应用程序可以提供一些 json 服务,但不知何故,当旧的过期时,我无法弄清楚如何请求一个新的。

这是我的中间件队列:

//some code

    $middlewareQueue

        ->add(new ErrorHandlerMiddleware(Configure::read('Error')))
        ->add(new AssetMiddleware([
            'cacheTime' => Configure::read('Asset.cacheTime'),
        ]))
        ->add(new RoutingMiddleware($this))
        ->add($csrf)
        ->add(new BodyParserMiddleware())
        ->add(new AuthenticationMiddleware($this));

   //more code

使用基本

如评论中所述,如果您想在令牌检索端点上使用表单身份验证器进行身份验证,则需要确保在身份验证器中包含该端点的 URL 路径 loginUrl选项。

那个选项接受一个数组,所以它应该像这样简单:

$service->loadAuthenticator('Authentication.Form', [
    'fields' => $fields,
    'loginUrl' => [
        '/users/login',
        '/api/users/token.json',
    ],
]);

您收到的错误是因为表单身份验证器根本没有应用于令牌端点,因此身份验证服务将转到下一个身份验证器 JWT 身份验证器,它未绑定到特定的端点,因此可以 运行 用于所有端点,JWT 身份验证器当然需要不同的有效负载,它会查找令牌,如果找不到,它将 return 错误状态FAILURE_CREDENTIALS_INVALID.