неверный токен lexik JWT при декодировании токена - PullRequest
0 голосов
/ 21 апреля 2020

Я сделал систему аутентификации с LexikJWTBundle, ниже мой security.yml, мой service.yml и мой config.yml

 security:
  encoders:
   FOS\UserBundle\Model\UserInterface: bcrypt

  providers:
    fos_userbundle:
      id: fos_user.user_provider.username

  role_hierarchy:
    ROLE_ADMIN: ROLE_USER
    ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

  firewalls:
    login:
      pattern: ^/api/login
      stateless: true
      anonymous: true
      provider: fos_userbundle
      logout: true
      form_login:
        check_path: /api/login_check
        username_parameter: username
        password_parameter: password
        success_handler: lexik_jwt_authentication.handler.authentication_success
        failure_handler: lexik_jwt_authentication.handler.authentication_failure
        require_previous_session: false
    register:
      pattern: ^/api/register
      stateless: true
      anonymous: true
    register-admin:
      pattern: ^/api/adminregister
      stateless: true
      anonymous: true
    api:
      pattern: ^/api
      stateless: true
      anonymous: true
      provider: fos_userbundle
      guard:
        authenticators:
          - jwt_token_authenticator
    admin-api:
      pattern: ^/api/admin
      provider: fos_userbundle
      stateless: true
      anonymous: true
      guard:
        authenticators:
          - jwt_token_authenticator
    # disables authentication for assets and the profiler, adapt it according to your needs
    dev:
      pattern: ^/(_(profiler|wdt)|css|images|js)/
      security: false

  access_control:
    - { path: ^/api/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api/adminregister, roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: 127.0.0.1, host: localhost }
    - { path: ^/api/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api/, roles: [IS_AUTHENTICATED_FULLY, ROLE_USER] }
    - { path: ^/api/admin/, roles: [IS_AUTHENTICATED_FULLY, ROLE_ADMIN] }
    - { path: ^/api/admin/users, roles: [IS_AUTHENTICATED_FULLY, ROLE_SUPER_ADMIN] }

и service.yml

service.yml

# Learn more about services, parameters and containers at
# https://symfony.com/doc/current/service_container.html
parameters:
    #parameter_name: value

services:
    # default configuration for services in *this* file
    _defaults:
        # automatically injects dependencies in your services
        autowire: true
        # automatically registers your services as commands, event subscribers, etc.
        autoconfigure: true
        # this means you cannot fetch services directly from the container via $container->get()
        # if you need to do this, you can override this setting on individual services
        public: false

    # makes classes in src/AppBundle available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    AppBundle\:
        resource: '../../src/AppBundle/*'
        # you can exclude directories or files
        # but if a service is unused, it's removed anyway
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

    # controllers are imported separately to make sure they're private
    # and have a tag that allows actions to type-hint services
    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

    # add more services, or override services that need manual wiring
    # AppBundle\Service\ExampleService:
    #     arguments:
    #         $someArgument: 'some_value'

    jwt_token_authenticator:
        class: AppBundle\Security\JwtTokenAuthenticator
        arguments: ['@lexik_jwt_authentication.encoder.lcobucci', '@doctrine.orm.entity_manager']

#service for cors preflight event
    AppBundle\Event\Listener\:
        resource: '../../src/AppBundle/Event/Listener/'
        tags:
            - { name: kernel.event_listener, event: kernel.response }

и config.yml

config.yml

// I've only put the lexik config

lexik_jwt_authentication:
  secret_key: "%kernel.project_dir%/config/jwt/private.pem" # required for token creation
  public_key: "%kernel.project_dir%/config/jwt/private.pem" # required for token verification
  pass_phrase: "%user_pass%" # required for token creation, usage of an environment variable is recommended
  token_ttl: 36000
  user_identity_field: username # key under which the user identity will be stored in the token payload
  clock_skew: 0

  # token encoding/decoding settings
  encoder:
    # token encoder/decoder service - default implementation based on the lcobucci/jwt library
    service: lexik_jwt_authentication.encoder.lcobucci

    # encryption algorithm used by the encoder service
    signature_algorithm: RS256

  # token extraction settings
  token_extractors:
    # look for a token as Authorization Header
    authorization_header:
      enabled: true
      prefix: Bearer
      name: Authorization

    # check token in a cookie
    cookie:
      enabled: false
      name: BEARER

    # check token in query string parameter
    query_parameter:
      enabled: false
      name: bearer

это функция для сторожевого аутентификатора

class JwtTokenAuthenticator extends AbstractGuardAuthenticator
{
    private $jwtEncoder;
    private $em;

    public function __construct(JWTEncoderInterface $jwtEncoder, EntityManager $em)
    {
        $this->jwtEncoder = $jwtEncoder;
        $this->em = $em;
    }

    public function supports(Request $request)
    {
        // look for header "Authorization: Bearer <token>"
        return $request->headers->has('Authorization')
            && 0 === strpos($request->headers->get('Authorization'), 'Bearer ');
    }

    public function getCredentials(Request $request)
    {
        $extractor = new AuthorizationHeaderTokenExtractor(
            'Bearer',
            'Authorization'
        );

        $token = $extractor->extract($request);

        if (!$token) {
            return new JsonResponse([
                "errorMessage" => "The token doesn't exist in authorization header please provide it like (Authorization: Bearer token)"
            ]);
        }

        return $token;
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        var_dump($credentials);
        try {
            $data = $this->jwtEncoder->decode($credentials);
        } catch (JWTDecodeFailureException $e) {

            $reason = $e->getReason();

            switch ($reason) {
                case 'invalid_token':
                    // throw new InvalidTokenException();
                    throw new CustomUserMessageAuthenticationException('The token is invalid');
                    break;
                case 'unverified_token':
                    throw new CustomUserMessageAuthenticationException('Unverified Token');
                    break;
                case 'expired_token':
                    // throw new ExpiredTokenException();
                    throw new CustomUserMessageAuthenticationException('The token is expired');
                    break;
                default:
                    throw new MissingTokenException();
                    break;
            }
        }

        $username = $data['username'];

        return $this->em
            ->getRepository('AppBundle:User')
            ->findOneBy(['username' => $username]);
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return true;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        return new JsonResponse([
            'message' => $exception->getMessageKey()
        ], 401);
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {

    }

    public function supportsRememberMe()
    {
        return false;
    }

    public function start(Request $request, AuthenticationException $authException = NULL)
    {
        throw new \Exception('Not used: entry_point from other authentication is used');
    }
}

токен существует в заголовке, но когда я пытаюсь его декодировать, у меня появляется ошибка {"message": "The token is invalid"} даже если токен подтвержден jwt.io, пожалуйста, мне нужна помощь, вот уже почти 3 недели я пытаюсь справиться с этой проблемой

...