terehinis/jwt-refresh-token-bundle
A Symfony bundle that adds refresh token support to JWT authentication. It lets you issue, rotate, and revoke long-lived refresh tokens alongside LexikJWTAuthenticationBundle, with Doctrine-backed storage and configurable expiration for secure, persistent user sessions.
Architecture fit. This is a Symfony bundle, not a Laravel package. It ships as a Symfony Bundle class with a DI extension, YAML configuration tree, Doctrine ORM/ODM-mapped refresh-token entity, and event subscribers hooked into Symfony's security firewall and LexikJWTAuthenticationBundle authentication flow. Laravel has no bundle registration, no Symfony kernel, no Doctrine-by-default entity mapping, and a guard/provider auth model that does not emit the security.authentication events this package listens to. There is no realistic path to composer require this into a Laravel application and have it function. Architecture fit for a Laravel stack is effectively zero; fit is only meaningful inside a Symfony application already using Lexik JWT.
Integration feasibility. Two honest options. (1) Adopt it only if a Symfony service already exists and the work is confined to that service, with Laravel calling it over HTTP. (2) Treat it as a reference implementation and port the domain logic into Laravel. The port surface is small and well understood: a refresh_tokens table (hashed token, user id, expiry, revoked flag, device/session metadata), a generator with cryptographic randomness, a rotation routine, reuse detection, and a revoke endpoint. That is days, not weeks, of engineering — and it removes the Symfony coupling entirely.
Technical risk. High, and mostly non-technical. Zero stars, zero dependents, no listed maintainer activity, and a name that strongly suggests a fork of the widely used gesdinet/jwt-refresh-token-bundle without an evident reason to fork. Security-sensitive code with no provenance is a governance problem: you cannot easily answer "who reviews this when a rotation vulnerability lands upstream?" Additional risk concentrates in token storage (are tokens hashed at rest or stored plaintext?), reuse detection semantics, PHP/Symfony version constraints that will age out, and Doctrine coupling that drags an ORM into a stack that may not want one.
Key questions.
gesdinet/jwt-refresh-token-bundle, and if so, what was changed and why not upstream the change?Stack fit. Poor as a dependency, good as a specification. Laravel's own primitives — Passport for OAuth2 refresh-token flows, Sanctum for first-party SPA/mobile sessions — cover the majority of use cases that lead teams to this package. Only reach past them if you specifically need stateless JWT access tokens paired with rotating, reuse-detecting refresh tokens and a revocation store you control.
Migration path. Recommended sequence: (a) confirm the requirement is genuinely "short-lived JWT + rotating refresh token," not "we want logout to work"; (b) if Passport fits, stop — it already implements refresh-token rotation and revocation with an actively maintained codebase; (c) if not, port the design into a first-party Laravel package rather than bridging Symfony. The port needs: a migration for the token table with a unique index on the token hash and an index on (user_id, revoked_at), a RefreshTokenService with issue, rotate, revoke, revokeAllForUser, a scheduled refresh_tokens:prune command, and a controller exposing /auth/refresh and /auth/logout. Keep the token opaque and random (not a JWT), hashed with SHA-256 before storage, delivered as an HttpOnly, Secure, SameSite cookie for browsers.
Compatibility. Since the package will not install under Laravel, "compatibility" is really about conceptual compatibility: the rotation and reuse-detection semantics transfer cleanly; the Symfony event-listener and Doctrine mapping do not. If a Symfony service is in play, verify the Symfony/PHP matrix against that service's pinned versions before committing — this is the one place the package might be genuinely lower-effort than a port.
Sequencing. Week 1: requirement clarification and a two-day spike proving whether Passport/Sanctum covers the flow. Week 2: decision gate — adopt upstream gesdinet (if Symfony), build first-party (if Laravel), or use Passport. Week 3–4: implementation, security review of the rotation logic, and load test on the refresh endpoint. Then staging with a forced-logout drill before production.
Maintenance. If adopted, you own it. A zero-dependent fork with no visible maintainer cadence will not receive timely security patches, and refresh-token code is exactly the class of code where a delayed patch is an incident. Budget for vendoring the source into your monorepo so you control upgrades, or accept the fork risk explicitly in writing.
Support. No vendor, no community, no SLA. Documentation is whatever upstream published plus whatever the fork changed. Internal runbooks for key rotation, token revocation, and "all users logged out unexpectedly" are mandatory and must be written by the adopting team, not inherited.
Scaling. The refresh-token table is the write hotspot: every rotation invalidates one row and inserts another, so a 1M-DAU product generating a refresh per session produces steady insert and update volume that must be indexed and pruned. Plan a nightly prune job with a retention window slightly beyond the token TTL, and consider Redis for the revocation/hot-token lookups if the auth path starts showing p99 latency. Token-family revocation on reuse detection requires a cheap lookup by family id.
Failure modes. Concurrent refreshes from the same client (multiple tabs, retrying mobile SDKs) trigger false-positive reuse detection and log users out — needs a short grace window or per-request idempotency. Clock skew between app servers shortens or extends token life unexpectedly; issue and validate against a single time source. A database outage means no refresh means a mass logout event across the fleet. Cookie-based delivery introduces CSRF exposure that must be handled at the route level. Key rotation for the access-token signing key must be coordinated with refresh validity or every session dies at once.
Ramp-up. Engineers touching this need to understand rotation, reuse detection, and revocation as concepts, and — if the Symfony package is somehow in play — Symfony's security firewall and Doctrine mapping, which is real onboarding cost on a Laravel team. The concepts are portable; the code is not. Estimate one to two days of design review plus a security pass for a competent Laravel engineer to build the equivalent, versus an open-ended ownership liability for importing this bundle.
How can I help you explore Laravel packages today?