8000 Add an opt-in refresher that renews the JWT cookie by jonmarkgo · Pull Request #2 · MLH/devise-jwt-cookie2 · GitHub
[go: up one dir, main page]

Skip to content

Add an opt-in refresher that renews the JWT cookie - #2

Merged
jonmarkgo merged 1 commit into
mainfrom
feat/opt-in-refresher
Oct 26, 2026
Merged

jonmarkgo merged 1 commit into
mainfrom
feat/opt-in-refresher

Conversation

@jonmarkgo
@jonmarkgo jonmarkgo commented Oct 26, 2026 •
Copy link
Copy Markdown
Member

Why

MLH Core needs to renew browser sessions centrally whenever it handles an authenticated request, so callers don't have to know about a refresh endpoint (review on MLH-Engineering/core#3406). This gem is where the cookie is read and written, so it gets an opt-in hook with a simple default, and Core supplies its own session rules.

What changes

  • New jwt_cookie.refresher setting, nil by default. With no refresher set, behaviour is unchanged.
  • Devise::JWT::Cookie::Refresher is the default implementation. It re-issues a still-valid token once it is past half its lifetime, and calls the model's on_jwt_dispatch so Allowlist records the new jti. A revoked, expired or wrong-scope token is never renewed.
  • The cookie strategy asks the refresher once per request, then authenticates with whichever token it ends up with. With a refresher configured, the strategy is valid even without a cookie, so a subclass can restore a session from its own credential. When no token results, the strategy passes and leaves the decision to the other strategies.
  • The middleware writes a refreshed token to the cookie. Dispatch and revocation still take precedence.
  • Version bumped to 0.7.0, and the README documents the setting.

A refresher is any object that responds to call(token, scope, env) and returns a new JWT, or nil to keep the current one.

Verification

bundle exec rake spec (Ruby 3.2): 37 examples, 0 failures, including new spec/features/token_refresh_spec.rb, which covers no refresher, a token before and after half-life, a revoked token, and a subclass recovering without a token. RuboCop is clean.

Release

Core will depend on ~> 0.7.0 once it's published to RubyGems.

Opened by a Claude Code agent on behalf of @jonmarkgo.

https://claude.ai/code/session_01CmZXZEDaL3ZbsgNLro2JXv


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

The cookie strategy can now ask a configured refresher for a new token
while it authenticates a request; the middleware writes the result to the
cookie unless the request revokes the token. The default refresher
re-issues a still-valid token past half its lifetime. Apps subclass it to
recover expired sessions or apply their own lifetime rules.

Claude-Session: https://claude.ai/code/session_01CmZXZEDaL3ZbsgNLro2JXv
@jonmarkgo
jonmarkgo merged commit a86c806 into main Oct 26, 2026
@jonmarkgo
jonmarkgo deleted the feat/opt-in-refresher branch October 26, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0