Skip to content

Reduce Supabase refresh-token churn (middleware + Realtime)#674

Draft
jon-bell wants to merge 3 commits into
stagingfrom
cursor--bc-a2fffe54-bc42-4253-841d-f7848a7dfe88-aa8d
Draft

Reduce Supabase refresh-token churn (middleware + Realtime)#674
jon-bell wants to merge 3 commits into
stagingfrom
cursor--bc-a2fffe54-bc42-4253-841d-f7848a7dfe88-aa8d

Conversation

@jon-bell
Copy link
Copy Markdown
Contributor

@jon-bell jon-bell commented Apr 5, 2026

Summary

Cuts unnecessary GoTrue refresh-token usage by avoiding getSession() on every middleware invocation and by stopping periodic Realtime getSession() polling when the browser client already refreshes the session.

Changes

  • Middleware: Parse the access JWT from Supabase SSR auth cookies (including chunked cookies). Call getSession() only when the token is missing, unreadable, lacks sub, or is past exp. Re-apply any refreshed cookies onto the final NextResponse (including redirects).
  • Middleware matcher: Exclude /api/* so API routes are not forced through session refresh / X-User-ID logic.
  • Realtime: bindRealtimeAuth() subscribes to onAuthStateChange and calls realtime.setAuth on INITIAL_SESSION, SIGNED_IN, and TOKEN_REFRESHED. Channel subscribe/reconnect uses getSession() only when realtime.accessTokenValue is still empty (bootstrap).
  • Tests: Unit tests for JWT payload decode/expiry gating and cookie session parsing.

Notes

  • Middleware still uses cookie-derived JWT for X-User-ID and route gating; server layouts continue to use getUser() for trusted checks where needed.
  • If production ever used symmetric JWTs for user access tokens, getClaims() would call getUser(); this path assumes asymmetric JWTs (typical for Supabase).

Verification

  • npx jest tests/unit/supabase-jwt-payload.test.ts tests/unit/middleware-session.test.ts
  • npm run lint
Open in Web Open in Cursor 

- Read JWT from SSR auth cookies for middleware; call getSession only when
  missing, invalid, or expired, then forward Set-Cookie on the response.
- Skip middleware for /api/* routes.
- Sync Realtime JWT from onAuthStateChange; use getSession only to bootstrap
  when accessTokenValue is empty.
- Add pure helpers and unit tests for JWT decode and cookie parsing.

Co-authored-by: Jonathan Bell <jon@jonbell.net>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 5, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f471186f-439f-46c8-98d7-c3c00aa13832

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@argos-ci
Copy link
Copy Markdown

argos-ci Bot commented Apr 5, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ⚠️ Changes detected (Review) 97 changed, 4 removed, 6 failures Apr 11, 2026, 1:44 PM

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.

2 participants