mrellerm/jwt-refresh-token-bundle
A Symfony bundle that adds JWT refresh token support to your authentication flow, letting clients exchange long-lived refresh tokens for new access tokens. Includes token rotation, Doctrine-backed storage, and integration with LexikJWTAuthenticationBundle.
Architecture fit. Despite the brief describing this as a "Laravel/PHP package," it is a Symfony bundle and will not drop into a Laravel application without an adapter layer. It is a personal fork of gesdinet/jwt-refresh-token-bundle — an established, actively maintained library that adds single-use refresh tokens over LexikJWTAuthenticationBundle. The fork's only differentiator is binding a client "fingerprint" to each issued refresh token and comparing it at refresh time, which is a sound and well-understood pattern (token binding / theft detection). Architecturally the underlying design is reasonable; the delta is small.
The real evaluation question is not "does the fingerprint feature work" but "should we consume a fork to get ~50–150 lines of comparison logic." Framed that way, the answer is almost always no — the feature is cheap to reimplement on a maintained base, and the fork carries all of upstream's surface area plus its own divergence.
Integration feasibility. Low-to-moderate. Three viable paths:
gesdinet/jwt-refresh-token-bundle and reimplement fingerprinting (recommended) — keep the maintained dependency for token lifecycle, rotation, TTL, and single_use semantics, and add a fingerprint column plus a listener/subscriber that validates on refresh.laravel/sanctum or PHP-Open-Source-Saver/jwt-auth and implement binding as a middleware. This is likely the correct answer given the framing of the request.Technical risk. High, concentrated in four areas:
ttl_update, single_use), and numerous bug fixes. This fork froze before most of that. Expect friction or outright failure on any modern Symfony.hash_equals (constant-time) and that fingerprint material is never logged or stored in plaintext-derived reversible form.Key questions for the maintainer/requester:
gesdinet, which would collapse the fork risk?Stack fit. If the target is Laravel, this bundle is a non-starter as a dependency — Symfony bundles rely on the Symfony DI container, event dispatcher, and bundle registration. Budget for reimplementation, not integration. If the target is genuinely Symfony, the fork is technically installable but should not be the default.
Recommended path — extract the concept, not the code:
gesdinet/jwt-refresh-token-bundle at its current maintained version (or the Laravel equivalent).fingerprint_hash column to the refresh token entity via a Doctrine migration (or Eloquent migration).hash_equals. On mismatch: revoke the entire token family for that user/device and force re-authentication, and emit an audit event.Migration path. If anything in the estate already depends on the fork, the exit is: identify the fork-specific columns/listeners, port the fingerprint logic into an event subscriber on upstream, run both in a staging environment against a token corpus, then cut over with a forced token rotation so no legacy tokens linger. Because refresh tokens are short-lived, the migration window is measured in days, not months — this is a genuinely cheap escape.
Compatibility. Do not assume the fork's composer.json constraints reflect reality. Run composer why-not against the target Symfony/PHP versions early; a 2020 fork will typically fail hard on PHP 8.1+ due to return types, dynamic properties, and Doctrine proxy signatures.
Sequencing. (1) Spike: 2–3 days to implement fingerprinting on maintained upstream and confirm behavior. (2) Threat model the fingerprint inputs and confirm privacy basis. (3) Ship in log-only mode behind a flag. (4) Enforce after 2–4 weeks of false-positive data. (5) Document the decision explicitly so the fork is not reintroduced later by someone who finds it on a search.
Maintenance. This is the dominant cost. A 0-star, 0-dependent fork with a single 2020 release has an effective maintenance owner count of zero besides us. Every upstream security release becomes a manual backport exercise. Realistically, budget 2–5 engineer-days per year for drift, plus unplanned work whenever a Symfony major version lands. That is a poor trade for a feature that is a few days to build.
Support. None. No issue triage, no documented upgrade path, no community to consult on edge cases. On-call engineers debugging a refresh failure at 2 a.m. will have only the source. Mitigate by ensuring whoever integrates it writes and owns an internal runbook — but recognize that this is a one-way door: once it is in the auth path, it is hard to rip out under pressure.
Scaling. Negligible throughput impact — one extra indexed column read per refresh, on an endpoint hit far less often than authenticated requests. The real scaling concern is token family revocation: mismatches that revoke all sessions for a user produce support load that scales with user count, not request count. Expect a spike in "I got logged out" tickets the first time enforcement is enabled.
Failure modes, ranked:
Ramp-up. Technically low — the codebase is small and the refresh-token lifecycle is well-trodden; a mid-level engineer gets productive in 2–3 days. The hidden ramp-up is organizational: someone must own a decision that this fork is intentional, and defend it in the next upgrade cycle. Without that, it becomes orphaned code that blocks a platform migration. Given 0 stars, 0 dependents, and a 2020 release, my recommendation is to not adopt the fork, capture the fingerprint requirement as an internal spec, and implement it on top of a maintained dependency in under a week.
How can I help you explore Laravel packages today?