Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Jwt Refresh Token Bundle Laravel Package

gesdinet/jwt-refresh-token-bundle

Symfony bundle for managing JWT refresh tokens with LexikJWTAuthenticationBundle. Provides secure refresh token handling, a configurable endpoint, Doctrine ORM/ODM support, and easy integration with Symfony security. Requires PHP 8.2+ and Symfony 6.4/7.2+/8.0+.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Verdict up front: this is not a Laravel package. gesdinet/jwt-refresh-token-bundle is a Symfony bundle. It extends symfony/security-bundle's firewall/authenticator system and requires LexikJWTAuthenticationBundle plus a Doctrine ORM/ODM ObjectManager. Nothing in it loads under Laravel's service container, its auth guards, or Eloquent. For a Laravel codebase, architecture fit is effectively zero without a rewrite; for a Symfony 6.4/7.2/8.0 stack it is a strong fit. Treat that distinction as the first decision gate, not a footnote.

Architecture fit (Symfony target). It slots in as a security authenticator on the same firewall as json_login and jwt, and Symfony orders it ahead of the JWT authenticator regardless of YAML order — which is precisely what allows an expired access token to be exchanged. It only claims requests matching check_path, so all other traffic authenticates normally. That is a clean, idiomatic seam: stateless short-lived JWT for authorization, a database-backed opaque-ish refresh record for revocation. The pattern is sound and worth copying conceptually even if the code isn't reusable.

Architecture fit (Laravel target). The concepts map cleanly (a refresh_tokens table, a rotation endpoint, a cleanup command, a guard/middleware), the implementation does not. A Laravel team would be reinventing roughly 300–600 lines of first-party code. Value extracted here is design guidance, not a dependency.

Integration feasibility. Good on Symfony, provided prerequisites land first: PHP ≥ 8.2, a Doctrine mapping strategy, and a firewall you control. The documented sharp edges are all integration-surface issues, not core design issues, and all have written fixes:

  • check_path must agree with the route; a mismatch yields "Unable to find the controller for path…" which misdirects you to the route.
  • auto_mapping: false or multiple entity managers silently break inheritance of the mapped superclass unless you declare the bundle's mapping explicitly.
  • doctrine:migrations:diff compares the whole database; without schema_filter it will emit drops for tables Doctrine doesn't own. This is the single scariest line in the README and it is not the bundle's bug — but it is the bundle's blast radius.

Technical risk.

  • Maintenance concentration. 712 stars and a single-maintainer pattern is thin social proof. The quality signals are genuinely strong (PHPStan level 10, Rector enabled, CI test matrix, coverage badge, CHANGELOG, staged UPGRADE guides from 1.5 through 3.0) — this reads as a well-run small project, not an abandoned one. But there is no second maintainer to absorb a bus-factor event.
  • Data-quality flags for the record. "Dependents: 0" contradicts the Packagist download badges, and the release date reads as forward-dated. Both suggest the dataset is stale or mis-scraped; verify against Packagist directly before any commercial decision.
  • Breaking-change history. The 2.0 removal of the route controller and the 1.x→3.0 rename path mean version upgrades are not free. Budget a real sprint, not an afternoon.
  • Credential lifetime. The docs explicitly argue against "never expires" TTLs and reject 0/negative values. That is a maturity signal, and it also means the product decision (how long may a user be absent?) is yours to make, not the library's.

Key questions.

  1. Is the target codebase Symfony or Laravel? If Laravel, this evaluation ends at "use Sanctum/Passport or build a 2–4 day internal equivalent."
  2. What is the session-absence window the product actually wants (7 days? 30? 90?), and is single-use rotation enabled?
  3. Who owns the refresh-token table's schema and cleanup job — platform or feature team?
  4. Does anything else in the org already issue tokens (SSO, mobile, partners)? Duplicate issuance is an audit problem.
  5. Are we on PHP 8.2+ and Symfony 6.4+? If not, we're pinned to a 1.x branch with no forward path.

Integration Approach

Stack fit.

  • Symfony 6.4 / 7.2 / 8.0, PHP 8.2+, Doctrine, LexikJWT already in place: adopt. Lowest-friction path, and the bundle is doing the job it was designed for.
  • Symfony but no LexikJWT: adopt both, but that's a second dependency decision with its own key-management work.
  • Laravel: do not integrate. Choose among Sanctum with a custom rotation table (recommended: smallest surface, first-party, no unmaintained dependency), laravel/passport if OAuth2 grant semantics are genuinely required, or a maintained JWT package if stateless access tokens are mandated — vetting that package's maintenance the way we vetted this one.
  • Mixed PHP estate: standardize on one issuance mechanism. Running this bundle in a Symfony service and something else in a Laravel app produces two revocation stories and two audit surfaces.

Migration path (Symfony 1.x → 3.0). Follow UPGRADE-RECTOR.md one release at a time rather than jumping. Rector handles the renames; the checklist covers what it can't — notably the 2.0 route change (no controller; the authenticator answers the route) and firewall check_path alignment. Do this on a branch with schema diffing disabled in CI until you've verified no destructive migration is emitted.

Compatibility. Pin to a minor (~3.x) and read the CHANGELOG at each bump. Rector + PHPStan 10 upstream means the codebase should be static-analysis-clean in your pipeline too — cheap signal that you're on a supported path.

Sequencing.

  1. Decision gate: confirm framework target and PHP/Symfony floors.
  2. Schema first, safely: add doctrine.dbal.schema_filter before generating any migration, then review the generated SQL line by line. If auto_mapping: false or multiple entity managers apply, wire the bundle's mapping explicitly.
  3. Config: refresh_token_class, ttl, rotation settings, object_manager if non-default.
  4. Wiring: entity/document class, route entry, refresh_jwt on the firewall with matching check_path, PUBLIC_ACCESS in access_control for login and refresh paths.
  5. Hardening: enable single-use rotation; define client retry behavior; add tests for expired-access/valid-refresh, revoked-refresh, and replayed-refresh.
  6. Ops: schedule gesdinet:jwt:clear, add table indexes, add alerting on refresh failure rate.
  7. Documentation: one internal page covering the check_path/route coupling and the migration caveat — these are the two things every future engineer will trip on.

Operational Impact

Maintenance. Low code churn, high version discipline. Budget roughly half a day per major upgrade plus test-cycle time; the UPGRADE docs make this predictable, which is the main reason the maintenance cost is defensible despite the bus factor. Vendor the version in composer.lock and treat upgrades as scheduled work, not reactive patching.

Support. Small community, single maintainer, issue volume that won't scale with your needs. Assume you own the failure modes: designate an internal owner (one backend engineer) who understands the authenticator priority and check_path coupling. External support is documentation-only.

Scaling. The refresh-token table grows monotonically with sessions — one row per active session, rotated on each use if single-use is enabled. That means row churn, not just growth. Concretely:

  • Index on the lookup column and on expiry; gesdinet:jwt:clear is expiry-driven and will table-scan without it.
  • Cleanup cron is mandatory, not optional. Miss it and the table grows unbounded and the revocation query degrades.
  • Concurrency is the real risk: single-use rotation means two simultaneous refreshes from the same credential (multi-tab web, mobile retry, flaky network) race, and the loser is logged out. That is a user-visible defect that will surface as support tickets before it surfaces in tests. Decide now whether the client serializes refreshes, retries on 401, or whether you accept the tradeoff for the security gain.
  • Mobile/SPA clients with short access-token TTLs will concentrate load on the refresh endpoint; it's a DB write path, so it needs its own capacity thinking, not just the JWT verification path.

Failure modes to instrument.

  • Refresh failure-rate spike → usually check_path/route drift after a routing refactor, or a bad ttl deploy.
  • Mass logouts → rotation race or clock skew between app servers.
  • Table bloat → cleanup job not scheduled, or cron silently failing.
  • Destructive migration → schema_filter absent in a database Doctrine doesn't fully own. This one is unrecoverable without backups; gate it in review.
  • Token theft → detectable in principle only if single-use rotation is on and you alert on reuse of a consumed token; without rotation, a stolen refresh token is valid until TTL expiry with no signal.

Ramp-up. A mid-level Symfony engineer integrates this in about a day following the README; add one to two days for rotation testing, cleanup scheduling, and the firewall/route fiddliness. Call it 2–3 engineer-days to production-ready with tests. The conceptual model (short access token + revocable rotating refresh credential) transfers directly to any other stack, so that learning isn't wasted even if the dependency is later replaced.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource