Session State Location Selector
by @quochungto
Route session state storage to the right location — Client Session State (cookies, JWT, hidden fields, URL parameters), Server Session State (in-memory or Re...
Example 1 — E-Commerce on an Elastic Cluster
Scenario: Online retailer with variable traffic (3x on sale days). Three-node cluster behind a load balancer with auto-scaling.
Trigger: New feature: multi-item shopping cart that must survive page refresh and browser close. Auth is already in-place using a session cookie.
Process:
1. Challenge statelessness: cart contents cannot be derived without the user's choices — genuinely stateful.
2. Scorecard: cart is medium-sized (~5–50 items), not security-sensitive (product IDs and quantities), needs durability (survive node death), needs cancellation (user can empty cart), cluster topology.
3. Routing: auth session ID → Client SS (existing, HttpOnly cookie). Cart → Database SS (elastic cluster + durability + cancellation). UI preferences → Client SS (small, not sensitive, fine to lose on client failure).
4. Security: session ID cookie: HttpOnly + Secure + SameSite=Strict. No sensitive data in Client SS beyond signed session ID.
5. Anti-pattern audit: confirm load balancer is NOT using sticky sessions for cart requests. Add session_id column to cart_items table. Implement background cleanup for abandoned carts (TTL 48h).
Output: Design record routing cart to Postgres cart_items table with session_id FK. Auth cookie stays Client SS. No node-pinning. Cleanup daemon specified.
Example 2 — Multi-Step Insurance Policy Editor (LOB App, Single Server)
Scenario: Line-of-business app for insurance agents. Single application server (no clustering). Agents edit complex policies across 6 wizard steps over 10–20 minutes. Policies have 80+ fields and nested objects.
Trigger: Current approach stores the entire partially-edited policy as a Java serialized object in HttpSession. Server runs out of memory under load.
Process:
1. Challenge statelessness: multi-step wizard with partial validation — genuinely stateful.
2. Scorecard: state is large (serialized policy graph ~200KB), not security-sensitive to external exposure (internal LOB app), single server (no clustering concern), slow serialization causing memory pressure.
3. Session-bloat anti-pattern detected: 200KB per active session in memory is the root cause.
4. Routing options: Database SS (persist pending policy rows with session_id field) is preferable — survives server restart, eliminates memory pressure, makes partial edits queryable (admin can see in-progress edits). Client SS is ruled out (200KB far exceeds cookie limits).
5. Implementation: add is_pending flag and session_id column to policy and policy_line tables. All "committed policies" queries add WHERE session_id IS NULL. Cleanup daemon deletes rows with session_id IS NOT NULL AND last_activity < NOW() - INTERVAL '4 hours'.
6. Note: single server means Server SS with external Redis is also viable as a simpler migration step. Document the trade-off.
Output: Design record recommending Database SS for policy editor state. Session-bloat anti-pattern resolved. Migration path from current HttpSession noted.
Example 3 — SPA with JWT Authentication
Scenario: React SPA with a Node.js/Express API backend. Team is debating JWT in localStorage vs JWT in HttpOnly cookie vs server-side session.
Trigger: Security review flagged localStorage JWT as vulnerable to XSS. Team wants guidance on the session state trade-off.
Process: 1. Challenge statelessness: auth context must persist — genuinely stateful. 2. Auth concern: small (user ID, roles, expiry ~300 bytes), security-sensitive (roles determine authorization), cluster topology (multiple API nodes behind a load balancer). 3. Scorecard: Client SS (HttpOnly cookie with signed JWT) wins on clustering (stateless API nodes), responsiveness (no server lookup), and size (tiny). Beats Server SS on clustering; beats Database SS on latency. 4. Security controls: HttpOnly cookie (XSS cannot read it), Secure flag, SameSite=Strict (CSRF protection). JWT signed with HMAC-SHA256. Short TTL (15 min access token) + longer HttpOnly refresh token (7 days). Re-validate JWT signature on every request. 5. Audit: localStorage flagged as anti-pattern for auth tokens — XSS exposure. Recommend HttpOnly cookie. 6. If refresh tokens need server-side revocation: store refresh token IDs in a Redis set per user (Server SS with external store). On logout, delete the Redis entry. Access tokens remain stateless until expiry.
Output: Design record: access JWT in HttpOnly cookie (Client SS). Refresh token revocation list in Redis (Server SS with external store). No localStorage. Anti-pattern (localStorage JWT) flagged and resolved.
clawhub install bookforge-session-state-location-selector