【问题标题】:A Token was not found in the TokenStorage在 TokenStorage 中找不到 Token
【发布时间】:2017-09-11 12:01:27
【问题描述】:

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

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

在 TokenStorage 中找不到 Token。

因此,以 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 }

谢谢!

【问题讨论】:

  • 显然,我只是在 refreshUser() 中返回 $user 并且它可以工作。我不太确定为什么 :)

标签: symfony


【解决方案1】:

添加

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

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

【讨论】:

    【解决方案2】:

    尝试实现AuthenticationFailureHandlerInterface并在onAuthenticationFailure中抛出异常。

    【讨论】:

      猜你喜欢
      • 2016-03-26
      • 2013-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-27
      • 1970-01-01
      • 2020-12-01
      相关资源
      最近更新 更多