Lexikjwtauthenticationbundle: JWTToken change fields for generate

Created on 19 Feb 2018  路  18Comments  路  Source: lexik/LexikJWTAuthenticationBundle

I use Symfony 3.3.10 with "lexik/jwt-authentication-bundle": "~2.0", and for user_identity_field I use email

lexik_jwt_authentication:
private_key_path: '%jwt_private_key_path%'
public_key_path:  '%jwt_public_key_path%'
pass_phrase:      '%jwt_key_pass_phrase%'
token_ttl:        '%jwt_token_ttl%'
user_identity_field: email

But after my user, call put request with email, I mean change email to something another. after have been change, when I call another api, example get user profile, I have error:

{
  "code": 401,
  "message": "Unable to load an user with property \"email\" = \"[email protected]\". If the user identity has changed, you must renew the token. Otherwise, verify that the \"lexik_jwt_authentication.user_identity_field\" config option is correctly set."
}

I understood, because I change email, which part for generating token, but I thought token saved in session and don't need regenerate token after change email or password.

My question how to change generating token fields, example I want use some constant field, example id?

Most helpful comment

login:
#
json_login:
#
username_path: email

All 18 comments

i have the same issue with two differences:
user_identity_field: id

and my id of the user entity is not auto increment:
/** * @ORM\Column(type="guid") * @ORM\Id * @ORM\GeneratedValue(strategy="UUID") */ private $id;

example: 9186b8bd-170b-11e8-82f8-480fcf324d89

and i use Symfony 4

The user entity method getusername is returning the email?

How can I change the user_identity_field username (default value) an email? I use symfony 4 and I get this error "message": "The key \"_username\" must be a string, \"NULL\" given.",.
Someone found a solution?

Hi @HecFranco,
did you find a solution ?

@HecFranco that's for the form_login part which is a symfony thing, not related to this bundle.
What you need is:

form_login:
    # ...
    username_parameter: email

Well, the error is

The key "email" must be a string, "NULL" given.

Then your HTTP request is incorrect, it just does not contain the email parameter.

Again, that's a symfony issue, form_login is part of symfony. You're looking for https://symfony.com/support

I use Symfony 3.3.11 with "lexik/jwt-authentication-bundle": "2.4.4", and user_identity_field - mobileNo

I get this error on consuming login API

eerror": {
"code": 400,
"message": "Bad Request",
"exception": [
{
"message": "The key "username" must be provided.",
......
}
]
}

I use Symfony 3.3.11 with "lexik/jwt-authentication-bundle": "2.4.4", and user_identity_field - mobileNo

I get this error on consuming login API

eerror": {
"code": 400,
"message": "Bad Request",
"exception": [
{
"message": "The key "username" must be provided.",
......
}
]
}

The answer to your problem is right there. If you are not using the key 'username' for authentication, you must specify it. For example, if you are using 'mobileNo' for authentication, you must specify it in your security.yaml.

form_login:
    # ...
    username_parameter: mobileNo

@EresDev thanks for help! I updated user_identity_field in config.yml and it worked

login:
#
json_login:
#
username_path: email

Hello :)) Have I misunderstood something? I want to use the field "email" to get the token at the endpoint "check_login". I have exactly the same problem as @RajeshwariN and have tried the solution of @EresDev. Or the one from @saifgo because I use json_login. But it doesn't work. "message": "The key "username" must be provided.".. I have change the following parts in the security.yaml

 providers:
        entity_provider:
            entity:
                class: App\Entity\User
                property: email

  firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login:
            pattern:  ^/login
            stateless: true
            anonymous: true
            json_login:
                username_path: email
                check_path: /login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure



md5-32107c599fd1ea47e4c6593baf37f71b



lexik_jwt_authentication:
    secret_key:       '%kernel.project_dir%/config/jwt/private.pem' # required for token creation
    public_key:       '%kernel.project_dir%/config/jwt/public.pem'  # required for token verification
    pass_phrase:      '' # required for token creation, usage of an environment variable is recommended
    token_ttl:        3600
    user_identity_field: email

@HashtagAssist Try by adding provider: entity_provider under login

Thanks for the quick response! Anyway that dont help :( i still get the the token by this json {"username":"test","password":"test"}.
{"username":"[email protected]","password":"test"} return "Invalid credentials" . And {"email":"[email protected]","password":"test"} result in a 400 (The key "username" must be provided.)

I have the same issue, while I am trying to redirect to login api route, but it gives me The key "password" must be provided. My controller returns a redirect response:

return $this->redirectToRoute('api_login', [
    'email'    => $user->getEmail(),
    'password' => $user->getPassword(),
], Response::HTTP_TEMPORARY_REDIRECT);

My security.yaml is configured with the following code:

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

    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email
        json_provider:
            entity:
                class: 'App\Entity\Security\User'
                property: 'id'


    firewalls:
        # Disabling the security for the web debug toolbar, the profiler and Assetic.
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

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

        api_registration:
            pattern: ^/api/auth/register
            stateless: true
            anonymous: true

        api_send_reset_email:
            pattern: ^/api/auth/reset/send-email
            stateless: true
            anonymous: true

        api_reset_password:
            pattern: ^/api/auth/reset/reset-password
            stateless: true
            anonymous: true

        api_login:
            pattern: ^/api/auth/login
            stateless: true
            anonymous: true
            provider: fos_userbundle
            json_login:
                check_path: /api/auth/login
                username_path: email
                password_path: password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

        api:
            pattern: ^/api
            stateless: true
            provider: json_provider
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
                provider: json_provider

        admin:
            pattern:            /admin(.*)
            context:            user
            form_login:
                provider:       fos_userbundle
                login_path:     sonata_user_admin_security_login
                use_forward:    true
                check_path:     sonata_user_admin_security_check
                failure_path:   null

            logout:
                path:           sonata_user_admin_security_logout

            remember_me:
                secret:      '%env(APP_SECRET)%'
                path:       /
                lifetime:   2592000 # 1 month in seconds

            anonymous:          true

        main:
            pattern: .*
            context: user
            anonymous: true
            logout: true

        default:
            anonymous: ~

    access_control:
#        # URL of FOSUserBundle which need to be available to anonymous users
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Admin login page needs to be access without credential
        - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Secured part of the site
        # This config requires being logged for the whole site and having the admin role for the admin part.
        # Change these rules to adapt them to your needs
        - { path: ^/eloquent-media/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
        - { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
        - { path: ^/api/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

    access_decision_manager:
        strategy: unanimous

And lexik_jwt_authentication.yaml:

lexik_jwt_authentication:
    secret_key:          '%env(resolve:JWT_SECRET_KEY)%'
    public_key:          '%env(resolve:JWT_PUBLIC_KEY)%'
    pass_phrase:         '%env(JWT_PASSPHRASE)%'
    token_ttl:           86400
    user_identity_field: id

Any suggestions?

I have the same issue, while I am trying to redirect to login api route, but it gives me The key "password" must be provided. My controller returns a redirect response:

return $this->redirectToRoute('api_login', [
    'email'    => $user->getEmail(),
    'password' => $user->getPassword(),
], Response::HTTP_TEMPORARY_REDIRECT);

My security.yaml is configured with the following code:

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

    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email
        json_provider:
            entity:
                class: 'App\Entity\Security\User'
                property: 'id'


    firewalls:
        # Disabling the security for the web debug toolbar, the profiler and Assetic.
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

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

        api_registration:
            pattern: ^/api/auth/register
            stateless: true
            anonymous: true

        api_send_reset_email:
            pattern: ^/api/auth/reset/send-email
            stateless: true
            anonymous: true

        api_reset_password:
            pattern: ^/api/auth/reset/reset-password
            stateless: true
            anonymous: true

        api_login:
            pattern: ^/api/auth/login
            stateless: true
            anonymous: true
            provider: fos_userbundle
            json_login:
                check_path: /api/auth/login
                username_path: email
                password_path: password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

        api:
            pattern: ^/api
            stateless: true
            provider: json_provider
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
                provider: json_provider

        admin:
            pattern:            /admin(.*)
            context:            user
            form_login:
                provider:       fos_userbundle
                login_path:     sonata_user_admin_security_login
                use_forward:    true
                check_path:     sonata_user_admin_security_check
                failure_path:   null

            logout:
                path:           sonata_user_admin_security_logout

            remember_me:
                secret:      '%env(APP_SECRET)%'
                path:       /
                lifetime:   2592000 # 1 month in seconds

            anonymous:          true

        main:
            pattern: .*
            context: user
            anonymous: true
            logout: true

        default:
            anonymous: ~

    access_control:
#        # URL of FOSUserBundle which need to be available to anonymous users
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Admin login page needs to be access without credential
        - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Secured part of the site
        # This config requires being logged for the whole site and having the admin role for the admin part.
        # Change these rules to adapt them to your needs
        - { path: ^/eloquent-media/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
        - { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
        - { path: ^/api/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

    access_decision_manager:
        strategy: unanimous

And lexik_jwt_authentication.yaml:

lexik_jwt_authentication:
    secret_key:          '%env(resolve:JWT_SECRET_KEY)%'
    public_key:          '%env(resolve:JWT_PUBLIC_KEY)%'
    pass_phrase:         '%env(JWT_PASSPHRASE)%'
    token_ttl:           86400
    user_identity_field: id

Any suggestions?

I assume you would have used this class use Symfony\Component\HttpFoundation\Request; to handle the requests. In symfony 5.2, somehow this class is not retrieving the post payloads.
Instead use this class use SymfonyBundles\JsonRequestBundle\JsonRequestBundle; after installing it using composer require symfony-bundles/json-request-bundle command.

I have the same issue, while I am trying to redirect to login api route, but it gives me The key "password" must be provided. My controller returns a redirect response:

return $this->redirectToRoute('api_login', [
    'email'    => $user->getEmail(),
    'password' => $user->getPassword(),
], Response::HTTP_TEMPORARY_REDIRECT);

My security.yaml is configured with the following code:

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

    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email
        json_provider:
            entity:
                class: 'App\Entity\Security\User'
                property: 'id'


    firewalls:
        # Disabling the security for the web debug toolbar, the profiler and Assetic.
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

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

        api_registration:
            pattern: ^/api/auth/register
            stateless: true
            anonymous: true

        api_send_reset_email:
            pattern: ^/api/auth/reset/send-email
            stateless: true
            anonymous: true

        api_reset_password:
            pattern: ^/api/auth/reset/reset-password
            stateless: true
            anonymous: true

        api_login:
            pattern: ^/api/auth/login
            stateless: true
            anonymous: true
            provider: fos_userbundle
            json_login:
                check_path: /api/auth/login
                username_path: email
                password_path: password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

        api:
            pattern: ^/api
            stateless: true
            provider: json_provider
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
                provider: json_provider

        admin:
            pattern:            /admin(.*)
            context:            user
            form_login:
                provider:       fos_userbundle
                login_path:     sonata_user_admin_security_login
                use_forward:    true
                check_path:     sonata_user_admin_security_check
                failure_path:   null

            logout:
                path:           sonata_user_admin_security_logout

            remember_me:
                secret:      '%env(APP_SECRET)%'
                path:       /
                lifetime:   2592000 # 1 month in seconds

            anonymous:          true

        main:
            pattern: .*
            context: user
            anonymous: true
            logout: true

        default:
            anonymous: ~

    access_control:
#        # URL of FOSUserBundle which need to be available to anonymous users
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Admin login page needs to be access without credential
        - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Secured part of the site
        # This config requires being logged for the whole site and having the admin role for the admin part.
        # Change these rules to adapt them to your needs
        - { path: ^/eloquent-media/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
        - { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
        - { path: ^/api/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

    access_decision_manager:
        strategy: unanimous

And lexik_jwt_authentication.yaml:

lexik_jwt_authentication:
    secret_key:          '%env(resolve:JWT_SECRET_KEY)%'
    public_key:          '%env(resolve:JWT_PUBLIC_KEY)%'
    pass_phrase:         '%env(JWT_PASSPHRASE)%'
    token_ttl:           86400
    user_identity_field: id

Any suggestions?

I assume you would have used this class use Symfony\Component\HttpFoundation\Request; to handle the requests. In symfony 5.2, somehow this class is not retrieving the post payloads.
Instead use this class use SymfonyBundles\JsonRequestBundle\JsonRequestBundle; after installing it using composer require symfony-bundles/json-request-bundle command.

I've already figured out, that trouble is in 307 response. It just does not support this behaviour. It can pass only those parameters, which are in the request. In this situation it would work, if I will pass email and password fields in the request body.

But thank you for the reply! :3

Was this page helpful?
0 / 5 - 0 ratings