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
.
使用身份验证插件,我无法通过 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
.