Lexikjwtauthenticationbundle: Sent JWT token does not give back user in controller.

Created on 29 Jun 2017  路  5Comments  路  Source: lexik/LexikJWTAuthenticationBundle

Hi,

I receive anonymous user when I try finding the user in controller via:
$user = $this->get('security.token_storage')->getToken()->getUser();

config.yml

lexik_jwt_authentication:
    private_key_path: '%kernel.root_dir%/../var/jwt/private.pem'
    public_key_path: '%kernel.root_dir%/../var/jwt/public.pem'
    pass_phrase: 'example'

security.yml

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

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email

    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        login:
            pattern:  ^/
            stateless: true
            anonymous: true
            form_login:
                login_path: fos_user_security_login
                provider: fos_userbundle
                check_path: /login_check
                require_previous_session: false
                username_parameter: _username
                password_parameter: _password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
            oauth:
                provider: fos_userbundle
                resource_owners:
                    facebook: facebook_login
                    google: google_login
                    linkedin: linkedin_login
                failure_path: app_login
                login_path: app_login
                oauth_user_provider:
                    service: app.provider.oauth
            logout:
                path:   fos_user_security_logout
                target: /

        register:
            pattern:  ^/register
            stateless: true
            anonymous: true

        api:
            pattern:  ^/api
            stateless: true
            anonymous: false
            provider: fos_userbundle
            guard:
                authenticators:
                    - app.jwt_token_authenticator
            lexik_jwt:
                authorization_header: # check token in Authorization Header
                    enabled: true
                    prefix:  Bearer

        refresh:
            pattern:  ^/api/token/refresh
            stateless: true
            anonymous: true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/doc, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/v1, role: IS_AUTHENTICATED_FULLY }
        - { path: ^/admin/, role: ROLE_ADMIN }

I have a question that when I send the jwt token in the Authorization header, I dont receive a preauthentication token in JWTTokenAuthenticator.php on line 100.

var_dump:

object(Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticationJWTUserToken)#569 (8) {
  ["rawToken":"Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticationJWTUserToken":private]=>
  string(835) "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJwcmFzaGFudC5iYWxhbkBob3RtYWlsLmNvbSIsImlhdCI6MTQ5ODYzNTc0NiwiZXhwIjoxNDk4NjM5MzQ2fQ.i4cjTLaurmNK_wgzjzRsRTHg4HdJR2q9A9bb_CVMETSBavMBQYRmG8DsWT15osqCDli1enaFMquVayTehyYX4aGez0TZtP_hB4U-S3Gxq7lslfzlFr6hDT_3lM3wRXKHiLTMvfwt-pnwfdUZdNB7TdU48NSGTRD8KWmeCjG9ifofPwBwxkKHElt4uA8_M78ksTMTsW4haKIZd_qSF6L0ubnhDWD8f7zZSw4E9rw_JYgbX0LsWedHkAB_9rjWHBAPfu-mw-BFrp8GA-2VyWr8ZbRDf3YTvIpRuqsAeYrXp52aFKxTUI9--tBkfVF1thP45a9y-0pIZ810tfFXZPRlKDK7dx8Jr9B16eT6c0Ea1fw4MC55qBvVFB2fO0bY-ylT3NiodQvYEGeO5VDybdahd1RBBvumRQmYCO4ZPaPe9tH2K46V82gP0t6dOZFipvJkaLWWRRZIiGgRRhvDWRfmne5pnnGiqjxMfPS1vC8cDGfmTIXxCuPJ1CgMhuytLIlr3seFaTG0qXzvr3VI8JF9tJ939T_d6mGDQpiQTjfu5uM2LZUKcWJB0pxTmM170gcG3WnmZ1L0gkqjeCZActtIg9TryYoonErF1atUi-w5rXtjw9q3uKXFLOAbZKZhZG0HqxnshcAkEy663Fo36q5CtpcM3gKkJ9bz26SKzhk8e84"
  ["payload":"Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticationJWTUserToken":private]=>
  NULL
  ["credentials":"Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken":private]=>
  NULL
  ["guardProviderKey":"Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken":private]=>
  NULL
  ["user":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
  NULL
  ["roles":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
  array(0) {
  }
  ["authenticated":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
  bool(false)
  ["attributes":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
  array(0) {
  }
}

I have a Security established exactly like the one in your Sandbox environment:

https://github.com/chalasr/lexik-jwt-authentication-sandbox/blob/master/src/AppBundle/Security/Guard/JWTAuthenticator.php

Do I need to make a change to my User entity?

Most helpful comment

I had the same problem (I mean, I don't know how to get the user from the current request inside a Service/Controller, when a JWT token is sent inside a Header/Get Parameter). After researching, I found this convenient solution:

  1. Inject SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorageInterface (for example in an attribute _tokenStorageInterface_)
  2. Inject LexikBundleJWTAuthenticationBundleServicesJWTTokenManagerInterface (for example, in an attribute _jwtManager_)
  3. Call _decode_ in _jwtManager_, and _getToken_ in _tokenStorageInterface_.

_Constructor of the service/controller (steps 1,2)_

public function __construct(TokenStorageInterface $tokenStorageInterface, JWTTokenManagerInterface $jwtManager)
    {
        $this->jwtManager = $jwtManager;
        $this->tokenStorageInterface = $tokenStorageInterface;
    }

_How to get user info from JWT Token? (step 3)_

$decodedJwtToken = $this->jwtManager->decode($this->tokenStorageInterface->getToken())

I hope this helps anybody that haven't found an exact solution to this question.

All 5 comments

Use the following two lines in my controller to fetch the user, if someone else has the same issue.

$preAuthToken = $this->jwtAuthenticator->getCredentials($request);
$response['user'] = $this->jwtManager->decode($preAuthToken);

I have created some REST API and tested it's working fine with jwt token on postman.
I need to call REST API through ajax so, how i can receive jwt tokent to send with REST API.

I had the same problem (I mean, I don't know how to get the user from the current request inside a Service/Controller, when a JWT token is sent inside a Header/Get Parameter). After researching, I found this convenient solution:

  1. Inject SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorageInterface (for example in an attribute _tokenStorageInterface_)
  2. Inject LexikBundleJWTAuthenticationBundleServicesJWTTokenManagerInterface (for example, in an attribute _jwtManager_)
  3. Call _decode_ in _jwtManager_, and _getToken_ in _tokenStorageInterface_.

_Constructor of the service/controller (steps 1,2)_

public function __construct(TokenStorageInterface $tokenStorageInterface, JWTTokenManagerInterface $jwtManager)
    {
        $this->jwtManager = $jwtManager;
        $this->tokenStorageInterface = $tokenStorageInterface;
    }

_How to get user info from JWT Token? (step 3)_

$decodedJwtToken = $this->jwtManager->decode($this->tokenStorageInterface->getToken())

I hope this helps anybody that haven't found an exact solution to this question.

Hi, does anyone know, how to do that in tests with cli (without request)?

Was this page helpful?
0 / 5 - 0 ratings