【发布时间】:2018-11-04 10:44:23
【问题描述】:
我指定我从 Symfony 开始。我想创建一个带有令牌的 API(没有 FOSRestBundle)作为身份验证手段。
我按照不同的教程进行此设置。我想要的是当“AuthTokenAuthenticator”类发现错误时,它返回一个json而不是html视图。
这是我的脚本:
AuthTokenAuthenticator
namespace AppBundle\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\HttpFoundation\JsonResponse;
class AuthTokenAuthenticator implements
SimplePreAuthenticatorInterface, AuthenticationFailureHandlerInterface
{
const TOKEN_VALIDITY_DURATION = 12 * 3600;
protected $httpUtils;
public function __construct(HttpUtils $httpUtils)
{
$this->httpUtils = $httpUtils;
}
public function createToken(Request $request, $providerKey)
{
//$targetUrlToken = '/auth-tokens'; // login
//$targetUrlUser = '/users/create'; // create account
/*if ($request->getMethod() === "POST" && $this->httpUtils->checkRequestPath($request, $targetUrlUser) || $request->getMethod() === "POST" && $this->httpUtils->checkRequestPath($request, $targetUrlToken) ) {
return;
}*/
$authTokenHeader = $request->headers->get('X-Auth-Token');
if (!$authTokenHeader) {
//return new JsonResponse(array("error" => 1, "desc" => "INVALID_TOKEN", "message" => "X-Auth-Token header is required"));
throw new BadCredentialsException('X-Auth-Token header is required');
}
return new PreAuthenticatedToken(
'anon.',
$authTokenHeader,
$providerKey
);
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
if (!$userProvider instanceof AuthTokenUserProvider) {
throw new \InvalidArgumentException(
sprintf(
'The user provider must be an instance of AuthTokenUserProvider (%s was given).',
get_class($userProvider)
)
);
}
$authTokenHeader = $token->getCredentials();
$authToken = $userProvider->getAuthToken($authTokenHeader);
if (!$authToken || !$this->isTokenValid($authToken)) {
throw new BadCredentialsException('Invalid authentication token');
}
$user = $authToken->getUser();
$pre = new PreAuthenticatedToken(
$user,
$authTokenHeader,
$providerKey,
$user->getRoles()
);
$pre->setAuthenticated(true);
return $pre;
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
}
/**
* Vérifie la validité du token
*/
private function isTokenValid($authToken)
{
return (time() - $authToken->getCreatedAt()->getTimestamp()) < self::TOKEN_VALIDITY_DURATION;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
throw $exception;
}
}
这是我没有通知令牌时的错误返回:
<!DOCTYPE html>
<html>
<head>
<title> X-Auth-Token header is required (500 Internal Server Error)
如何获得返回的 json 响应? 如果我尝试执行 return new JsonResponse(array("test" => "KO")) (简单示例),我会收到此错误:
<title> Type error: Argument 1 passed to Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager::authenticate() must be an instance of Symfony\Component\Security\Core\Authentication\Token\TokenInterface, instance of Symfony\Component\HttpFoundation\JsonResponse given, called in /Users/mickaelmercier/Desktop/workspace/api_monblocrecettes/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SimplePreAuthenticationListener.php on line 101 (500 Internal Server Error)
【问题讨论】:
-
请把介绍翻译成英文。
-
您是否尝试在路由定义中强制使用 json 格式?