在TokenStorage中找不到令牌

时间:2017-09-11 12:01:28

标签: symfony

所以我使用Guard Authenticators对用户进行身份验证。

登录和注销成功,但是当我尝试在其他路由上请求时,它会抛出AuthenticationCredentialsNotFoundException说

  

在TokenStorage中找不到令牌。

因此,回应401。

这是我的身份验证员类:

class ApiAuthenticator extends AbstractGuardAuthenticator implements LogoutSuccessHandlerInterface
    {
        public function getCredentials(Request $request)
        {
            if ($request->getPathInfo() != '/login' || !$request->isMethod('POST')) {
                return;
            }

            $data = json_decode($request->getContent(), true);

            return [
                'username' => $data['_username'],
                'password' => $data['_password'],
            ];
        }

        public function getUser($credentials, UserProviderInterface $userProvider)
        {
            return $userProvider->loadUserByUsername($credentials);
        }

        public function checkCredentials($credentials, UserInterface $user)
        {
            if (!$user instanceof User) {
                throw new \TypeError();
            }

            return true;
        }

        public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
        {
            return new JsonResponse([ 'error' => 'Invalid Credentials!'], Response::HTTP_UNAUTHORIZED);    }

        public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
        {
            $response = [
                'success' => 'Success!',
                'customer' => [
                    'name' => 'Fullname',
                    'memberSince' => 'mm/dd/yyyy'

                ]
            ];

            return new JsonResponse($response, Response::HTTP_OK);
        }

        public function start(Request $request, AuthenticationException $authException = null)
        {   
            return new Response('', Response::HTTP_UNAUTHORIZED);
        }

        public function supportsRememberMe()
        {

        }

        public function onLogoutSuccess(Request $request)
        {
            $request->getSession()->invalidate();
            return new Response();
        }
    }

这是我的UserProvider类:

class UserProvider implements UserProviderInterface
{
    private $apiHelper;
    private $session;

    public function __construct(ApiHelper $apiHelper, Session $session)
    {
        $this->apiHelper = $apiHelper;
        $this->session = $session;
    }

    public function loadUserByUsername($credentials)
    {
        $response = $this->apiHelper->generateAccessToken($credentials['username'], $credentials['password']);

        if (isset($response['access_token'])) {

            $this->session->set('authAccessToken', $response['access_token']);
            $this->session->set('authExpiresIn', $response['expires_in']);
            $this->session->set('authRefreshToken', $response['refresh_token']);

            $accessToken = new AccessToken();
            $accessToken->setAccessToken($response['access_token']);
            $accessToken->setExpiresIn($response['expires_in']);
            $accessToken->setTokenType($response['token_type']);
            $accessToken->setScope($response['scope']);
            $accessToken->setRefreshToken($response['refresh_token']);

            return new User($accessToken);
         }

         throw new UsernameNotFoundException(
            sprintf('Username "%s" does not exist.', '')
        );
    }

    public function refreshUser(UserInterface $user)
    {
        if (!$user instanceof User) {
            throw new UnsupportedUserException(
                sprintf('Instances of "%s" are not supported.', get_class($user))
            );
        }

        return $user;

            // return $this->loadUserByUsername([
            //     'password' => $user->getPassword(),
            //     'username' => $user->getUsername(),
            // ]);
    }

    public function supportsClass($class)
    {
        return User::class === $class;
    }
}

这是我的security.yml

security:
    providers:
        user_provider:
            id: user_provider

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            http_basic: ~
            pattern: ^/
            provider: user_provider
            logout:
                path:   /logout
                success_handler: api_authenticator
            guard:
                authenticators:
                    - api_authenticator
    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/test, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, roles: IS_AUTHENTICATED_FULLY }

谢谢!

2 个答案:

答案 0 :(得分:0)

尝试实现AuthenticationFailureHandlerInterface并在onAuthenticationFailure中引发异常。

答案 1 :(得分:0)

添加

main:
    # ...
    anonymous: true
    # ...

security.yml 将有助于将该异常转换为 AccessDeniedException(通常应该在开发模式下转换为 InsufficientAuthenticationException 并重定向到登录在 prod 模式下使用内核异常侦听器,但这取决于您)。