markitosgv/JWTRefreshTokenBundle

Multiple refresh tokens in the database

fpignatelli opened this issue · 3 comments

I have configured LexikJWTAuthenticationBundle + JWTRefreshTokenBundle in Symfony 6.1/mySQL.
Everything works correctly, but if I send username and password several times (for example from Postman), more refresh tokens referring to the user are inserted in the database.
In this way a user (malicious or not) can send repeated calls filling the database with a refresh token.

Is it a configuration error? some idea?

Thanks in advance.

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)%'
    user_identity_field: username
    token_ttl: 3600
    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

gesdinet_jwt_refresh_token.yaml

gesdinet_jwt_refresh_token:
  ttl_update: true
  return_expiration: true
  single_use: false

security.yaml

    [...]
    firewalls:
        login:
            pattern: ^/api/login
            stateless: true
            json_login:
                check_path: /api/login_check
                username_path: username
                password_path: password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
        api:
            pattern: ^/api
            stateless: true
            entry_point: jwt
            jwt: ~
            refresh_jwt:
                check_path: /api/token/refresh # or, you may use the `api_refresh_token` route name

    [...]

    access_control:
        - { path: ^/api/login, roles: PUBLIC_ACCESS }
        - { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/public, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY }

same for me, and event more if I run token refresh endpoint it return back new JWT token but same refresh token. If I'm not mistaken refresh should invalidate provided refresh token and create new one

same here

@bogdan-dubyk This behaviour is configurable by using the single_use parameter:

https://github.com/markitosgv/JWTRefreshTokenBundle#single-use-tokens