A Next.js BFF stores OAuth/JWT tokens in httpOnly cookies rather than server-side session state. Is that a valid BFF, and what does it require?

next.js 16.2.10 · verified Jul 16, 2026

Fix: Storing the real access/refresh tokens in httpOnly cookies is NOT the IETF draft's default BFF — that one keeps tokens in server-side session state and gives the browser an opaque session id. Putting tokens in cookies is the draft's permitted "client-side session" variant, and it carries a condition most implementations miss: the BFF SHOULD encrypt its cookie contents (e.g. a JWE via `jose`). Unencrypted tokens in an httpOnly cookie are a spec deviation, not a shortcut. Encryption protects the embedded tokens against cookie-jar/disk access; it does NOT prevent session hijacking, and the draft says so explicitly. Practical guidance: use ONE encrypted cookie holding {access_token, refresh_token, access_token_exp} rather than splitting them across path-scoped cookies — once encrypted, path scoping buys nothing (both are opaque blobs only the server can read) and it actively hurts, because a catch-all proxy route that cannot see the refresh token cannot refresh server-side, forcing a reactive 401→refresh→retry round trip onto the client. With one cookie the proxy unseals, refreshes proactively when near expiry, re-seals, and sets the updated cookie on the response. Note the draft ranks BFF > Token-Mediating Backend > browser-only OAuth client "in decreasing order of security" and recommends BFF; TMB differs by handing the access token to the browser so it calls resource servers directly.

bffoauthnext.jsauthcookiesjwesession

References