JWTRefreshTokenBundle: Symfony 6 Unable to find the controller for path "/api/token/refresh". The route is wrongly configured.

In symfony 6 refresh token not working properly because it unable to find the controller. Do you have any solution for this case ?

security.yaml -> firewalls:

# ...
 firewalls:
        api_token_refresh:
            pattern: ^/api/token/refresh
            stateless: true
            refresh_jwt: ~

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

        login:
            pattern: ^/api/login
            stateless: true
            json_login:
                check_path: /api/login
                username_path: uusr_login
                password_path: uusr_pass
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

        api:
            pattern: ^/api/
            stateless: true
            provider: app_user_provider
            jwt: ~

        main:
            provider: app_user_provider
            logout:
                path: app_logout
# ...

router.yaml:


api_login:
    path: /api/login
    methods: ['POST']

gesdinet_jwt_refresh_token:
    path: /api/token/refresh

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 11
  • Comments: 26 (3 by maintainers)

Most upvoted comments

Hi !

I recently had the same problem with Symfony 6.2 and PHP 8.1.

Fortunately, I got the solution.

It seems that the refresh route has been configured to accept only some pattern of url. I test some url for this route and the controller was not the problem. The problem came from the path of our routes. By the look of it, routes path like /auth/refresh/token are bad where routes path like api/refresh/token (whith is recommended by the bundle in doc), refresh/token or token/refresh are good !

I don’t take more time to test which path occur an error or not but I think the problem is that the bundle auto configure some routes path and not others.

That is my configuration :

# route.yaml
# ...
api_refresh_token:
    path: /token/refresh
    methods: [POST]
# ...
# security.yaml
security:
# ...
    firewalls:
    # ...
        api_token_refresh:
            pattern: /token/refresh
            stateless: true
            provider: app_user_provider # provider in database
            refresh_jwt:
                check_path: api_refresh_token
    # ...
# ...
    access_control:
        # ...
        - { path: ^/token/refresh$, roles: PUBLIC_ACCESS }
        # ...
# ...

I have removed the path configuration in config/routes/gesdinet_jwt_refresh_token.yaml created by Symfony Recipes, with this configuration it will not work again. I recommend you to remove this file because it isn’t helpful anymore. Then, my configuration is like this :

# gesdinet_jwt_refresh_token:
    # path: /token/refresh
# ...

Now, it works so good ! So. That solution is just temporary, I guest they will fix it. I wish I helped you. 👍🏾

This happens because in the latest release the authenticator only reports support for requests where the refresh token is present. A fix has been merged (just now) but has not yet been included in a release.

So sending an empty request will result in a 404, but using the route as intended (ie. sending the refresh token with the request in a manner the extractor can find it) should work as expected.

Until the next release, a dirty work-around could be to add the following to your route configuration:

api_token_refresh:
    path: /api/token/refresh
    controller: gesdinet.jwtrefreshtoken::refresh

In this case, using the route as intended will still trigger the authenticator system (and not use the defined controller) but any request to the same path where the authenticator does not trigger, will end up using the controller instead of returning a 404. Just don’t forget to remove the controller config when a new version is released.

See 1 and 2.

If anyone have route issues configuring this with SF 6.1, here is my solution: Add users provider to refresh firewall, configure new route with different path than /api/token/refresh. For example:

# security.yaml
    firewalls:
        # ...
        refresh:
            provider: my_user_provider
            refresh_jwt:
                check_path: api_refresh_token
# routes.yaml
api_refresh_token:
    path: /api/token/renew

Work well with configuration :

    refresh_jwt:
        refresh_jwt:
            check_path: /api/token/refresh
        provider:  app_user_provider

You need to add provider to api_token_refresh

Ex:

api_token_refresh:
            pattern: ^/api/token/refresh
            stateless: true
            provider: app_user_provider
            refresh_jwt: ~

after a LOT of debugging, I found that the solution is to simply add check_path: gesdinet_jwt_refresh_token in the security.yaml, like this:

firewalls:
    refresh:
        // ...
        refresh_jwt: 
            check_path: gesdinet_jwt_refresh_token

hello, i dont know if u still need the solution , any way this ts my configuration and it works jut fine : symfony 6.2 on the routes.yaml file :

api_refresh_token: path: /api/token/refresh

on the security.yaml file this is my firewall :

firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    login:
        pattern: ^/api/login
        stateless: true
        json_login:
            check_path: /api/login_check
            success_handler: lexik_jwt_authentication.handler.authentication_success
            failure_handler: lexik_jwt_authentication.handler.authentication_failure
        logout:
            path: /logout
    api_token_refresh:
        pattern: ^/api/token/refresh
        stateless: true
        refresh_jwt:
            check_path: /api/token/refresh
    api:
        pattern: ^/api
        stateless: true
        jwt: ~
    main:
        custom_authenticators:
            - App\Security\MyGoogleAuthenticator
            - App\Security\MyLinkedinAuthenticator
        entry_point: App\Security\MyGoogleAuthenticator

also do not forget to add the access control :

  • { path: ^/api/token/refresh, roles: PUBLIC_ACCESS }

@SergeMezui16 Very very thanks! ❤️ Your solution works! 😀

Hi !

I recently had the same problem with Symfony 6.2 and PHP 8.1.

Fortunately, I got the solution.

It seems that the refresh route has been configured to accept only some pattern of url. I test some url for this route and the controller was not the problem. The problem came from the path of our routes. By the look of it, routes path like /auth/refresh/token are bad where routes path like api/refresh/token (whith is recommended by the bundle in doc), refresh/token or token/refresh are good !

I don’t take more time to test which path occur an error or not but I think the problem is that the bundle auto configure some routes path and not others.

That is my configuration :

# route.yaml
# ...
api_refresh_token:
    path: /token/refresh
    methods: [POST]
# ...
# security.yaml
security:
# ...
    firewalls:
    # ...
        api_token_refresh:
            pattern: /token/refresh
            stateless: true
            provider: app_user_provider # provider in database
            refresh_jwt:
                check_path: api_refresh_token
    # ...
# ...
    access_control:
        # ...
        - { path: ^/token/refresh$, roles: PUBLIC_ACCESS }
        # ...
# ...

I have removed the path configuration in config/routes/gesdinet_jwt_refresh_token.yaml created by Symfony Recipes, with this configuration it will not work again. I recommend you to remove this file because it isn’t helpful anymore. Then, my configuration is like this :

# gesdinet_jwt_refresh_token:
    # path: /token/refresh
# ...

Now, it works so good ! So. That solution is just temporary, I guest they will fix it. I wish I helped you. 👍🏾

@youassi that is working, thanks!

Same issue here, the comment from @mv-developer didn’t solved the problem…