markitosgv / JWTRefreshTokenBundle

Implements a Refresh Token system over Json Web Tokens in Symfony
MIT License
663 stars 159 forks source link

accept: application/json header dosent works #306

Open tydoo opened 2 years ago

tydoo commented 2 years ago

Symfony 6.0.6

I use Api platform.

When i try /api/token/refresh with the accept: application/json header, its doent works.

But its works without the header.


Request :

curl -X 'POST' \
  'https://127.0.0.1:8000/api/token/refresh' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "refresh_token": "bd952f8c8c936d59daee30650fec607845142a39d745150c2c5a273667b91682b0989f1ee84f30095c551f6fa267c6d0c9a14a3eeef8e70cf06397c43661523e"
}'

Response :

{
    "type": "https:\/\/tools.ietf.org\/html\/rfc2616#section-10",
    "title": "An error occurred",
    "status": 404,
    "detail": "Unable to find the controller for path \"\/api\/login\/refresh\". The route is wrongly configured.",
    "class": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException",
    "trace": [
        {
            "namespace": "",
            "short_class": "",
            "class": "",
            "type": "",
            "function": "",
            "file": "C:\\Users\\thoma\\OneDrive\\Documents\\Developpement web\\Sites web\\lebackoffice\\vendor\\symfony\\http-kernel\\HttpKernel.php",
            "line": 136,
            "args": []
        },
        {
            "namespace": "Symfony\\Component\\HttpKernel",
            "short_class": "HttpKernel",
            "class": "Symfony\\Component\\HttpKernel\\HttpKernel",
            "type": "->",
            "function": "handleRaw",
            "file": "C:\\Users\\thoma\\OneDrive\\Documents\\Developpement web\\Sites web\\lebackoffice\\vendor\\symfony\\http-kernel\\HttpKernel.php",
            "line": 74,
            "args": [
                [
                    "object",
                    "Symfony\\Component\\HttpFoundation\\Request"
                ],
                [
                    "integer",
                    1
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\HttpKernel",
            "short_class": "HttpKernel",
            "class": "Symfony\\Component\\HttpKernel\\HttpKernel",
            "type": "->",
            "function": "handle",
            "file": "C:\\Users\\thoma\\OneDrive\\Documents\\Developpement web\\Sites web\\lebackoffice\\vendor\\symfony\\http-kernel\\Kernel.php",
            "line": 202,
            "args": [
                [
                    "object",
                    "Symfony\\Component\\HttpFoundation\\Request"
                ],
                [
                    "integer",
                    1
                ],
                [
                    "boolean",
                    true
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\HttpKernel",
            "short_class": "Kernel",
            "class": "Symfony\\Component\\HttpKernel\\Kernel",
            "type": "->",
            "function": "handle",
            "file": "C:\\Users\\thoma\\OneDrive\\Documents\\Developpement web\\Sites web\\lebackoffice\\vendor\\symfony\\runtime\\Runner\\Symfony\\HttpKernelRunner.php",
            "line": 35,
            "args": [
                [
                    "object",
                    "Symfony\\Component\\HttpFoundation\\Request"
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\Runtime\\Runner\\Symfony",
            "short_class": "HttpKernelRunner",
            "class": "Symfony\\Component\\Runtime\\Runner\\Symfony\\HttpKernelRunner",
            "type": "->",
            "function": "run",
            "file": "C:\\Users\\thoma\\OneDrive\\Documents\\Developpement web\\Sites web\\lebackoffice\\vendor\\autoload_runtime.php",
            "line": 29,
            "args": []
        },
        {
            "namespace": "",
            "short_class": "",
            "class": "",
            "type": "",
            "function": "require_once",
            "file": "C:\\Users\\thoma\\OneDrive\\Documents\\Developpement web\\Sites web\\lebackoffice\\public\\index.php",
            "line": 5,
            "args": [
                [
                    "string",
                    "C:\\Users\\thoma\\OneDrive\\Documents\\Developpement web\\Sites web\\lebackoffice\\vendor\\autoload_runtime.php"
                ]
            ]
        }
    ]
}

My configuration

routes.yaml

controllers:
    resource: ../src/Controller/
    type: annotation

kernel:
    resource: ../src/Kernel.php
    type: annotation

api_login:
    path: /api/login

gesdinet_jwt_refresh_token:
    path: /api/login/refresh

security.yaml

security:
    enable_authenticator_manager: true
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
        App\Entity\User:
            algorithm: auto
    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email
    firewalls:
        login:
            pattern: ^/api/login$
            stateless: true
            json_login:
                check_path: /api/login
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
        api:
            request_matcher : App\RequestMatcher\ApiRequestMatcher
            stateless: true
            jwt: ~
        api_token_refresh:
            pattern: ^/api/login/refresh$
            stateless: true
            refresh_jwt: ~
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: app_user_provider
            custom_authenticator: App\Security\AppAuthenticator
            remember_me:
                secret: '%kernel.secret%'
                lifetime: 604800 # 1 week in seconds
                path: /
                samesite: strict
            logout:
                path: security.logout
                target: security.login

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#the-firewall

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/(login|fr|en|reset-password),   roles: PUBLIC_ACCESS }
        - { path: ^/api/login,                      roles: PUBLIC_ACCESS }
        - { path: ^/api/token/refresh,              roles: PUBLIC_ACCESS }
        - { path: ^/,                               roles: IS_AUTHENTICATED_FULLY }

gesdinet_jwt_refresh_token.yaml

gesdinet_jwt_refresh_token:
    single_use: true

This header is not removable on Api platform (and Swagger UI)

mbabker commented 2 years ago

Please try with the 1.1 release. The issue shouldn't have been the Accept header, but other quirks fixed with the release.