PHPackages                             yivoff/jwt-refresh-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. yivoff/jwt-refresh-bundle

ActiveSymfony-bundle[Authentication &amp; Authorization](/categories/authentication)

yivoff/jwt-refresh-bundle
=========================

Token Refresh for JWT. Independent of persistence layer, splitting id/hash for verification

v3.0.0(1y ago)35.8k[1 PRs](https://github.com/yivi/YivoffJwtRefreshBundle/pulls)MITPHPPHP &gt;=8.3CI passing

Since Nov 4Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/yivi/YivoffJwtRefreshBundle)[ Packagist](https://packagist.org/packages/yivoff/jwt-refresh-bundle)[ RSS](/packages/yivoff-jwt-refresh-bundle/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependencies (9)Versions (19)Used By (0)

yivoff/jwt-refresh-bundle
=========================

[](#yivoffjwt-refresh-bundle)

[![PHP Version Require](https://camo.githubusercontent.com/b2fc5f66cacaf9ffd6b35d3f01d5e1cf89c972664dbc825dfea35f4028efef4e/687474703a2f2f706f7365722e707567782e6f72672f7969766f66662f6a77742d726566726573682d62756e646c652f726571756972652f706870)](https://packagist.org/packages/yivoff/jwt-refresh-bundle)[![Latest Stable Version](https://camo.githubusercontent.com/6e3f5db90a4dceda5e1b2d67fd9a6a17ab5c62a645d1185a7c13755fc29b45f9/687474703a2f2f706f7365722e707567782e6f72672f7969766f66662f6a77742d726566726573682d62756e646c652f76)](https://packagist.org/packages/yivoff/jwt-refresh-bundle)[![Total Downloads](https://camo.githubusercontent.com/097b9c2382f726a25b46a34ab6cc66441e0e874065a533c256f5ece9c7bdb0f8/687474703a2f2f706f7365722e707567782e6f72672f7969766f66662f6a77742d726566726573682d62756e646c652f646f776e6c6f616473)](https://packagist.org/packages/yivoff/jwt-refresh-bundle)[![Latest Unstable Version](https://camo.githubusercontent.com/982de681cd8c4a0e9b425458f96e83c1d5b6379bf0c705d65abc071a97bcaa85/687474703a2f2f706f7365722e707567782e6f72672f7969766f66662f6a77742d726566726573682d62756e646c652f762f756e737461626c65)](https://packagist.org/packages/yivoff/jwt-refresh-bundle)[![License](https://camo.githubusercontent.com/71e5761cc5c2daf8d4725d91a8716bd8efd1cb620112a8aafef68f88bdf73acf/687474703a2f2f706f7365722e707567782e6f72672f7969766f66662f6a77742d726566726573682d62756e646c652f6c6963656e7365)](https://packagist.org/packages/yivoff/jwt-refresh-bundle)[![Tests](https://github.com/yivi/YivoffJwtRefreshBundle/actions/workflows/bundle_tests.yaml/badge.svg)](https://github.com/yivi/YivoffJwtRefreshBundle/actions/workflows/bundle_tests.yaml/badge.svg)[![codecov](https://camo.githubusercontent.com/f410314049b1d7cf33a8c534fc18f60683d745973c75b02ba681dfd2d3a7161a/68747470733a2f2f636f6465636f762e696f2f67682f796976692f5969766f66664a77745265667265736842756e646c652f6272616e63682f6d61737465722f67726170682f62616467652e7376673f746f6b656e3d344a4454513449444e37)](https://app.codecov.io/gh/yivi/YivoffJwtRefreshBundle)

- [Description](#description)
- [Requirements](#requirements)
- [Installation and setup](#installation-and-setup)
    - [Installation](#installation)
    - [Token Provider Implementation](#token-provider-implementation)
        - [Purgable Provider](#purgable-provider)
    - [Security Integration](#security-integration)
    - [Bundle Configuration](#bundle-configuration)
    - [Purge Command](#purge-command)
- [Usage](#usage)

Description
-----------

[](#description)

This package provides a way to generate "refresh tokens" that users can use to obtain a new authorization token (JWT) when the previous one expires. This is a companion for \[lexik/LexikJWTAuthenticationBundle\], and it is not usable on its own.

The package does not make any assumptions about the persistence layer for storing the refresh tokens. You can use any backend or library (Mysql, Mongo, Redis, flat-file, etc) as long as there is a service that implements a basic interface provided by the package: [`RefreshTokenProviderInterface`](https://github.com/yivi/YivoffJwtRefreshBundle/blob/master/Contracts/RefreshTokenProviderInterface.php)

Tokens are stored with an identifier and a hashed verifier, instead of a plain-text verifier, for added security.

Each refresh-token can only be used once to get a new auth-token. When used, the old refresh-token is deleted, and a new refresh-token is generated.

You should setup the time-to-live for the refresh-tokens to be significantly higher than the time to live of the auth-tokens.

Requirements
------------

[](#requirements)

Requires PHP 8+, Symfony 5.3+

Installation and Setup
----------------------

[](#installation-and-setup)

### Installation

[](#installation)

```
$ composer require yivoff/jwt-refresh-bundle
```

### Token Provider Implementation

[](#token-provider-implementation)

This package makes no assumptions about the nature of your token provider. To be able to use it you'll need to implement your own, either a regular Doctrime ORM repository or whatever better suits your project.

You'll need to have a service that implements `RefreshTokenProviderInterface`, and then on the bundle configuration, on `yivoff_jwt_refresh.token_provider_service` you'll write down the service ID that the bundle will use for getting/adding/removing tokens.

This service is responsible, directly or indirectly, of mediating with your persistance layer of choice, and should return/accept [`RefreshTokenInterface`](https://github.com/yivi/YivoffJwtRefreshBundle/blob/master/Contracts/RefreshTokenInterface.php) instances. Either your application token entity implements this interface directly, or your token-provider adapts between your native entities, and the provided [`RefreshToken`](https://github.com/yivi/YivoffJwtRefreshBundle/blob/master/Model/RefreshToken.php) class.

#### Purgable Provider

[](#purgable-provider)

Your token provider can additionally implement `PurgableRefreshTokenProviderInterface`, to have a convenience method to clear up all the stale tokens. This is necessary if you want to use the included [purge command](#purge-command)

### Security integration

[](#security-integration)

On the same firewall where the JWT Authenticator provides with a login check, setup a new guard authenticator provided by this bundle (`Yivoff\JwtTokenRefresh\Security\Authenticator`).

E.g, for a typical configuration:

```
firewalls:
    login:
        pattern:  ^/login
        stateless: true
        anonymous: true
        provider: users_in_memory
        custom_authenticators:
          - Yivoff\JwtTokenRefresh\Security\Authenticator
        json_login:
            check_path:               /login_check
            success_handler:          lexik_jwt_authentication.handler.authentication_success
            failure_handler:          lexik_jwt_authentication.handler.authentication_failure
```

Notice the content for `firewall.login.guard.authenticators`.

### Bundle Configuration:

[](#bundle-configuration)

**Yaml**

```
yivoff_jwt_refresh:
    token_provider_service: 'App\Repository\AuthRefreshTokenRepository'
    token_ttl: 3600
    parameter_name: 'refresh_token'
```

**XML**

```

    App\Infrastructure\Redis\Repository\AuthRefreshTokenRepository
    refresh_token
    3600

```

- `token_provider_service`

    This is a **required** key. The string value must be the *id* for a service that implements `RefreshTokenProviderInterface`.
- `token_ttl`

    The bundle provides a default value of 3600. Change it if you want the token to be available for more or less time.
- `parameter_name`

    Name of the HTTP `POST` parameter that will hold the refresh token. `refresh_token` by default.

### Purge command

[](#purge-command)

If `symfony/console` is installed on your project, and your Token Provider implements `PurgableRefreshTokenProviderInterface`, you can use a command to delete all the existing tokens that have already expired.

The command can simply be executed by running `bin/console yivoff:jwt_refresh:purge_expired_tokens`. On non-error conditions, it produces no output.

### Usage

[](#usage)

On any regular JSON authentication, the bundle will inject a refresh token on a field named as the `parameter_name`defined on the configuration. A typical request/response would be:

**Request**

```
POST http://localhost:7099/login_check
Content-Type: application/json

{
  "username": "john_user",
  "password": "abcd"
}
```

**Response**

```
HTTP/1.1 200 OK
Date: Sat, 09 May 2020 16:01:37 GMT
Connection: close
Content-Type: application/json

{
  "token": "ey...token...131",
  "refresh_token": "bd8b1a304dc39dda3d10a38788b2ebf7:f52ac998773d552a0c639c2f85ffa5f2e18df2f1a3f528c9ddc3fcd8c6ba2f31"
}
```

It is not necessary to register a new route for the "refresh" path. To get a new authentication JWT, you simply call the same login path with regular `POST` call with a HTTP parameter with the same name and value that we received previously:

```
POST http://localhost:7099/login_check
Content-Type: application/x-www-form-urlencoded

refresh_token=bd8b1a304dc39dda3d10a38788b2ebf7:f52ac998773d552a0c639c2f85ffa5f2e18df2f1a3f528c9ddc3fcd8c6ba2f31
```

### Events

[](#events)

If you want your application to react to successful or failed refresh attempts (logging, etc.), the library emits events that you can listen to.

#### Failure

[](#failure)

When the refresh attempt fails for whatever reason, the library emits a `Yivoff\JwtRefreshBundle\Event\JwtRefreshTokenFailed`event.

The event has three public properties:

- `?string tokenId`: The identifier for the refresh token. This will be null if the payload was invalid, and no identifier could be retrieved from the request.
- `?string userIdentifier`: The identifier for the user that ows the token. this will be null if the payload was invalid, or if we couldn't find a token for the request `tokenId`.
- `FailType $failType`: This is an enum that describes the failure type encountered:
    - `FailType::PAYLOAD`: Payload could not be parsed.
    - `FailType::NOT_FOUND`: Token by this id could not be found.
    - `FailType::INVALID`: Token was found, but verifier was invalid.
    - `FailType::EXPIRED`: Token was found, but it was already expired.

#### Success

[](#success)

On success, a `Yivoff\JwtRefreshBundle\Event\JwtRefreshTokenSucceeded` event is emitted. This simply includes the properties:

- `string tokenId`: the identifier for the refresh token
- `string userIdentifier`: the identifier for the user that owns the token

###  Health Score

48

—

FairBetter than 94% of packages

Maintenance66

Regular maintenance activity

Popularity23

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity78

Established project with proven stability

 Bus Factor1

Top contributor holds 64.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~102 days

Recently: every ~259 days

Total

16

Last Release

521d ago

Major Versions

v0.6.0 → v1.0.02021-08-27

v1.0.0 → v2.0.02021-12-29

2.2.2 → v3.0.02025-01-22

PHP version history (5 changes)v0.5.0PHP ^7.4

v0.5.3PHP &gt;=7.4

v0.6.0PHP &gt;=8.0

v2.0.0PHP &gt;=8.1

v3.0.0PHP &gt;=8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/e0d85d0f1920fcb556200094ef25fe6d1c6c1540dac4b9118a0045d59b2a92bd?d=identicon)[yivi](/maintainers/yivi)

---

Top Contributors

[![yivi](https://avatars.githubusercontent.com/u/1815039?v=4)](https://github.com/yivi "yivi (49 commits)")[![ivan-eo](https://avatars.githubusercontent.com/u/47242361?v=4)](https://github.com/ivan-eo "ivan-eo (27 commits)")

---

Tags

authenticationjwtphpsymfony-5symfony-bundle

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/yivoff-jwt-refresh-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/yivoff-jwt-refresh-bundle/health.svg)](https://phpackages.com/packages/yivoff-jwt-refresh-bundle)
```

###  Alternatives

[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.5M376](/packages/easycorp-easyadmin-bundle)[web-auth/webauthn-framework

FIDO2/Webauthn library for PHP and Symfony Bundle.

51390.8k2](/packages/web-auth-webauthn-framework)[web-auth/webauthn-symfony-bundle

FIDO2/Webauthn Security Bundle For Symfony

65474.5k9](/packages/web-auth-webauthn-symfony-bundle)[2lenet/crudit-bundle

The easy like Crud'it Bundle.

1615.6k12](/packages/2lenet-crudit-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
