Compare CookieHttpSessionIdResolver and HeaderHttpSessionIdResolver. When would you switch from cookies to a header?
answer
- HttpSessionIdResolver = how the ID travels
- Cookie default: name SESSION, DefaultCookieSerializer
- Header: xAuthToken() → X-Auth-Token
- Header = client must echo it manually
- Non-browser / cross-origin → header
basics
~20 sAn HttpSessionIdResolver decides how the session ID travels between client and server. The cookie resolver (default) uses a Set-Cookie/Cookie. The header resolver reads/writes it in an HTTP header (e.g. X-Auth-Token), which suits non-browser clients like mobile apps or SPAs across domains.
solid answer
~50 s`HttpSessionIdResolver` is the Spring Session strategy that extracts the session ID from a request and writes it back on the response. `CookieHttpSessionIdResolver` is the default: it uses a cookie (via a `CookieSerializer`, default name `SESSION`) — great for browsers, automatic on every request, and lets you control `HttpOnly`, `Secure`, `SameSite`, and path. `HeaderHttpSessionIdResolver` instead reads the ID from and writes it to an HTTP header, commonly `X-Auth-Token` (there are factory methods `xAuthToken()` and `authenticationInfo()` for the `Authorization` header). You switch to the header resolver for non-browser or cross-origin clients — native mobile apps, or JS clients where cookies are awkward (CORS credentials, third-party-cookie restrictions). The client must then read the header from the login response and echo it on every subsequent request; there's no automatic sending like cookies. You configure it by exposing an `HttpSessionIdResolver` bean.
code
java · 21 lines@Configuration
@EnableRedisHttpSession
public class SessionConfig {
// Non-browser clients: carry the session id in X-Auth-Token
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
// Alternatively, harden the default cookie resolver:
// @Bean
// CookieSerializer cookieSerializer() {
// DefaultCookieSerializer s = new DefaultCookieSerializer();
// s.setCookieName("SESSION");
// s.setUseHttpOnlyCookie(true);
// s.setUseSecureCookie(true);
// s.setSameSite("Lax");
// return s;
// }
}go deeper
Know that the resolver decides whether the session ID rides in a cookie or a header, and cookie is the default.
Name the two implementations, the default cookie name SESSION, xAuthToken(), and when to pick header (mobile/cross-origin).
Discuss security trade-offs: HttpOnly/SameSite loss with header, CSRF implications, DefaultCookieSerializer hardening, CORS exposure.
Frame the client-contract change, migration strategy across clients, and token-storage/XSS responsibility shift.
## What an HttpSessionIdResolver is Spring Session needs to know two things per request: **how to find the session ID coming in**, and **how to communicate a (new or changed) session ID going out**. That strategy is the `org.springframework.session.web.http.HttpSessionIdResolver` interface, with three methods: - `resolveSessionIds(HttpServletRequest)` → the candidate session IDs on the request - `setSessionId(request, response, id)` → tell the client the current/new ID - `expireSession(request, response)` → instruct the client to drop the ID The `SessionRepositoryFilter` calls the resolver on every request. ## CookieHttpSessionIdResolver (the default) - Transports the ID in an HTTP **cookie**. Serialization/parsing is delegated to a **`CookieSerializer`** — the default is **`DefaultCookieSerializer`**, and the default cookie name is **`SESSION`** (Base64-encoded value), not `JSESSIONID`. - Via `DefaultCookieSerializer` you control the security-relevant attributes: - **`setUseHttpOnlyCookie(true)`** — JS can't read it (XSS mitigation). - **`setUseSecureCookie(true)`** — only sent over HTTPS. - **`setSameSite("Lax"/"Strict"/"None")`** — CSRF / cross-site behavior. `None` requires `Secure`. - **`setCookiePath(...)`, `setDomainName(...)`, `setCookieName(...)`.** - It also supports **cookie-based session-ID rotation** hints and can carry multiple sessions (used by Spring Session's multi-account support). - **Why default:** browsers send cookies automatically on every same-site request, so the app 'just works' with zero client code. ## HeaderHttpSessionIdResolver - Transports the ID in an **HTTP header** instead of a cookie. - Factory methods: - `HeaderHttpSessionIdResolver.xAuthToken()` → header **`X-Auth-Token`**. - `HeaderHttpSessionIdResolver.authenticationInfo()` → header **`Authorization`**. - Or `new HeaderHttpSessionIdResolver("Your-Header")`. - **No automatic transmission:** the client must capture the header from the response (e.g. on login the server sets `X-Auth-Token: <id>`) and **explicitly send it back** on every request. This is a client responsibility. ## When to choose which | Scenario | Resolver | |---|---| | Server-rendered web app / browser | Cookie (default) | | Native mobile app (no cookie jar you want to rely on) | Header | | SPA/API where cookies are painful (CORS credentials, third-party-cookie blocking, multiple origins) | Header | | You need `HttpOnly`/`SameSite`/`Secure` browser protections | Cookie | **Trade-offs of the header approach:** you lose the browser's automatic `HttpOnly`/`SameSite` protections, so the client must store the token safely (and you're now responsible for XSS exposure of that token). CSRF risk changes: header-based IDs aren't sent automatically by the browser, which actually *reduces* CSRF exposure (an attacker's forged request won't carry your custom header), but you take on secure client-side storage. ## How to configure Expose an `HttpSessionIdResolver` bean; Spring Session picks it up. You can only have one active resolver. ## Gotchas - Switching resolver changes the **client contract** — existing browser cookie flows won't send the header, so you can't silently swap in production without updating clients. - With the header resolver, **CORS** must expose the response header (`Access-Control-Expose-Headers`) so JS can read `X-Auth-Token`. - The default cookie name is `SESSION`, a frequent surprise for people expecting `JSESSIONID`.
- With HeaderHttpSessionIdResolver, how does the client get and use the session ID?The server writes it on the response header (e.g. X-Auth-Token) — typically on the first request/login. The client reads and stores it, then sends it back in that header on every subsequent request. Nothing is automatic like cookies.
- What's the default cookie name Spring Session uses, and how do you harden it?SESSION (not JSESSIONID). Harden via a DefaultCookieSerializer bean: setUseHttpOnlyCookie(true), setUseSecureCookie(true), and setSameSite("Lax"/"Strict").
saying these in an interview costs you the question
- Saying the default cookie is JSESSIONID (Spring Session uses SESSION)
- Assuming the header resolver auto-sends the ID like a cookie
- Claiming you can run both resolvers simultaneously
- Forgetting CORS Access-Control-Expose-Headers is needed for JS to read the header