- Feature: Session Management with Cloudflare KV
- Target Completion: 2-3 hours
- Confidence Score: 8/10 - Well-documented pattern but requires careful security considerations
- Created: 2025-11-09
A production-ready session management system using Cloudflare KV for storage. Includes authentication flow, secure cookie handling, React Context provider for global auth state, and middleware for protecting endpoints. This example demonstrates best practices for session management including security considerations, automatic expiration, and proper cookie configuration.
-
Pattern: Worker API Handler
- Location:
worker/index.ts:1-12 - Description: Basic worker with URL routing pattern
- Relevance: Foundation for adding auth API routes
- Location:
-
Pattern: TypeScript Configuration
- Location:
tsconfig.worker.json - Description: Worker-specific TypeScript config
- Relevance: Ensures types work correctly for KV operations
- Location:
-
Pattern: React Context Pattern
- Location: React 19 documentation
- Description: Global state management with Context API
- Relevance: Used for SessionProvider implementation
-
Convention: Response.json for API responses
- Example:
worker/index.ts:6-8 - Application: Use Response.json for all auth API responses
- Example:
-
Convention: URL pathname matching for routes
- Example:
url.pathname.startsWith("/api/") - Application: Route auth endpoints under
/api/auth
- Example:
- Test Framework: Not currently configured
- Pattern: Manual testing via curl with cookie handling
- Location: Development workflow
-
Resource: Cloudflare KV
- URL: https://developers.cloudflare.com/kv/
- Key Sections: API, TTL, Best Practices
- Version: Latest (Workers runtime)
- Gotchas: Eventually consistent; use for read-heavy workloads
-
Resource: Workers Sessions Pattern
- URL: https://developers.cloudflare.com/workers/examples/sessions/
- Key Sections: Cookie handling, Session storage
- Version: Latest
- Gotchas: Must use HttpOnly cookies for security
-
Resource: HTTP Cookies (MDN)
- URL: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
- Key Sections: Security, SameSite, HttpOnly
- Version: Latest
- Gotchas: SameSite=Strict may break legitimate cross-site flows
-
Example: Cloudflare Workers Sessions
- Source: Cloudflare documentation
- Relevance: Pattern for secure cookie handling
- Cautions: Must include all security flags (HttpOnly, Secure, SameSite)
-
Example: React Authentication Context
- Source: React patterns
- Relevance: Global auth state management
- Cautions: Don't store sensitive data in context (it's not encrypted)
-
Practice: HttpOnly Cookies
- Why: Prevents XSS attacks by making cookies inaccessible to JavaScript
- How: Set httpOnly: true in cookie options
- Warning: Never store sensitive session data in localStorage
-
Practice: Secure Session IDs
- Why: Prevents session hijacking
- How: Use crypto.getRandomValues() for session ID generation
- Warning: Don't use predictable session IDs (timestamps, sequential numbers)
-
Practice: Session Expiration
- Why: Limits window of opportunity for stolen sessions
- How: Use KV TTL for automatic cleanup
- Warning: Balance security with user experience (not too short)
-
Practice: Password Security (for production)
- Why: Protects user credentials
- How: Always hash passwords (bcrypt, scrypt, Argon2)
- Warning: NEVER store plain-text passwords
┌──────────────┐ Login ┌──────────────┐ Session ┌──────────┐
│ React │ ──────────> │ Worker │ ──────────> │ KV │
│ SessionProvider│ <────────── │ Endpoints │ <────────── │ Storage │
│ │ Set-Cookie │ │ Get/Put │ │
└──────────────┘ └──────────────┘ └──────────┘
│
│ Middleware
▼
┌──────────────┐
│ Protected │
│ Endpoints │
└──────────────┘
Flow:
1. User submits login form → POST /api/auth/login
2. Worker validates credentials
3. Worker creates session ID and stores in KV
4. Worker sends Set-Cookie header with session ID
5. Browser includes cookie in subsequent requests
6. Worker validates session from cookie
7. Protected endpoints check for valid session
- Purpose: Define session, user, and API response types
- Location:
examples/database/kv-sessions/types.ts - Dependencies: None
- Interface: Exported interfaces, validation functions, cookie helpers
- Purpose: Session management class for worker operations
- Location:
examples/database/kv-sessions/worker-middleware.ts - Dependencies: Types, KV binding
- Interface: SessionManager class with CRUD operations
- Purpose: Handle login, logout, and session retrieval
- Location:
examples/database/kv-sessions/worker-endpoints.ts - Dependencies: Types, Middleware, KV binding
- Interface: Request handlers and router function
- Purpose: Global authentication state management
- Location:
examples/database/kv-sessions/SessionProvider.tsx - Dependencies: Types, Worker API
- Interface: React Context Provider component
- Purpose: Easy access to session context
- Location:
examples/database/kv-sessions/useSession.ts - Dependencies: SessionProvider
- Interface: Custom React hook + example components
// User (application model)
interface User {
id: string;
email: string;
name: string;
createdAt: Date;
}
// Session data (stored in KV)
interface SessionData {
userId: string;
email: string;
name: string;
createdAt: string; // ISO string
expiresAt: string;
}
// Session (API model)
interface Session {
sessionId: string;
user: User;
expiresAt: Date;
}
// Login request
interface LoginRequest {
email: string;
password: string;
}
// Session configuration
interface SessionConfig {
cookieName: string;
sessionTTL: number;
cookieOptions: {
httpOnly: boolean;
secure: boolean;
sameSite: 'strict' | 'lax' | 'none';
path: string;
};
}-
Endpoint:
POST /api/auth/login- Purpose: Authenticate user and create session
- Request:
{ email, password } - Response:
{ success: true, data: Session }+ Set-Cookie header - Authentication: None (public endpoint)
-
Endpoint:
POST /api/auth/logout- Purpose: Destroy session
- Request: Session cookie
- Response:
{ success: true, message }+ Clear-Cookie header - Authentication: Optional (works with or without session)
-
Endpoint:
GET /api/auth/session- Purpose: Get current session
- Request: Session cookie
- Response:
{ success: true, data: Session }or 401 - Authentication: Required (session cookie)
- Cloudflare account with Workers enabled
- Wrangler CLI installed
- Node.js 18+ and npm
- Project set up with Vite + React + TypeScript
Goal: Provision a KV namespace in Cloudflare
Commands:
npx wrangler kv namespace create SESSIONS
npx wrangler kv namespace create SESSIONS --previewFiles to Create/Modify:
wrangler.jsonc- Add KV binding configuration
Validation: Namespace IDs appear in wrangler output
Goal: Connect KV namespace to the worker
Files to Create/Modify:
wrangler.jsonc- Add[[kv_namespaces]]section
Pseudocode Approach:
Validation: npm run cf-typegen succeeds and generates SESSIONS types
Goal: Define all session-related types
Files to Create/Modify:
examples/database/kv-sessions/types.ts- All interfaces and helpers
Reference Pattern: Standard TypeScript interface patterns
Validation: No TypeScript errors, types export correctly
Goal: Create SessionManager class
Files to Create/Modify:
examples/database/kv-sessions/worker-middleware.ts- SessionManager class
Pseudocode Approach:
class SessionManager {
// 1. Parse cookies from request
// 2. Get session from KV
// 3. Validate expiration
// 4. Create new sessions with crypto-secure IDs
// 5. Store in KV with TTL
// 6. Generate Set-Cookie headers
}Validation: Class methods work correctly
Goal: Create login, logout, and session endpoints
Files to Create/Modify:
examples/database/kv-sessions/worker-endpoints.ts- All endpoint handlers
Pseudocode Approach:
async function login(request, env) {
// 1. Validate credentials (mock for now)
// 2. Create session with SessionManager
// 3. Return JSON + Set-Cookie header
}Reference Pattern: See existing worker handler in worker/index.ts
Validation: Test with curl commands
Goal: Connect auth handlers to worker
Files to Create/Modify:
worker/index.ts- Add routing for/api/auth
Pseudocode Approach:
if (url.pathname.startsWith('/api/auth')) {
return handleAuthRequest(request, env);
}Validation: Routes respond correctly
Goal: Global auth state management
Files to Create/Modify:
examples/database/kv-sessions/SessionProvider.tsx- Context provider
Pseudocode Approach:
function SessionProvider({ children }) {
// 1. Manage session state
// 2. Fetch session on mount
// 3. Provide login/logout functions
// 4. Handle loading and error states
// 5. Provide context value
}Reference Pattern: React 19 Context API
Validation: Provider renders without errors
Goal: Easy access to session context
Files to Create/Modify:
examples/database/kv-sessions/useSession.ts- Hook and example components
Pseudocode Approach:
function useSession() {
// 1. Get context
// 2. Throw if used outside provider
// 3. Return context value
}Validation: Hook works in components
Goal: Add provider to app root
Files to Create/Modify:
src/main.tsx- Wrap app with SessionProvider
Validation: Session state available throughout app
- Client-side errors: Display in UI, maintain user session state
- Server-side errors: Return structured JSON errors with appropriate status codes
- Validation errors: Return 400 Bad Request for invalid credentials
- Network errors: Catch fetch errors and display user-friendly messages
- Session errors: Clear session and redirect to login
- Cookie errors: Log and return generic error (don't expose cookie details)
-
Edge Case: Expired session
- Solution: Check expiration before returning session; auto-delete if expired
-
Edge Case: Invalid session ID
- Solution: Return null session (treat as logged out)
-
Edge Case: Concurrent logins
- Solution: Allow multiple sessions per user (each gets unique session ID)
-
Edge Case: Session revocation
- Solution: Delete from KV; cookie becomes invalid
-
Edge Case: Cookie blocked by browser
- Solution: Display message to enable cookies
-
Edge Case: XSS attempts to read cookies
- Solution: HttpOnly flag prevents JavaScript access
-
Edge Case: CSRF attacks
- Solution: SameSite cookie attribute provides protection
- Coverage Target: Core session management functions
- Key Test Cases:
- Session creation and validation
- Cookie parsing and serialization
- Session ID generation (randomness)
- Expiration checking
- Mock Strategy: Mock KV namespace responses
- Test Scenarios:
- Complete auth flow: Login → Get Session → Logout
- Session expiration handling
- Invalid credentials handling
- Cookie handling across requests
- Setup Required: Local KV namespace
- Login with valid credentials
- Login with invalid credentials (should fail)
- Session persists across page refreshes
- Logout clears session
- Session expires after TTL
- Protected endpoints reject unauthenticated requests
- Protected endpoints accept authenticated requests
- Cookies have correct security flags (HttpOnly, Secure, SameSite)
- Test on both local and production environments
# Ensure Wrangler is installed
wrangler --version
# Verify KV is available
wrangler kv --help
# Check Node version
node --version # Should be 18+# Type checking (run after each step)
npm run build
# Generate types after KV configuration
npm run cf-typegen
# Test worker locally
npm run dev# Build succeeds
npm run build
# Deploy to production
npm run deploy
# Test login endpoint
curl -X POST https://your-worker.workers.dev/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"demo@example.com","password":"password123"}' \
-c cookies.txt \
-v- Open browser to development URL
- Login with demo credentials
- Verify session appears in React DevTools
- Refresh page - verify session persists
- Logout and verify session is cleared
- Check browser DevTools:
- Network tab: verify Set-Cookie headers
- Application tab: verify cookie properties
- Verify protected endpoints work when logged in
None for basic implementation.
For production, consider:
{
"dependencies": {
"bcryptjs": "^2.4.3" // For password hashing
}
}- Node: 18.x or higher
- Wrangler: 3.x or higher
- React: 19.x
- TypeScript: 5.x
Not applicable for KV-only implementation.
For production with D1 user storage:
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
name TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);Not applicable - this is an example feature
- Create and configure KV namespace
- Test locally with
npm run dev - Deploy worker with
npm run deploy - Test production endpoints
- Monitor session creation/deletion in KV dashboard
- Check for errors in Workers logs
- All validation gates pass
- Login creates session successfully
- Session cookie is set with correct flags
- Session persists across requests
- Logout clears session
- Protected endpoints require authentication
- No TypeScript errors
- Build succeeds
- Cookies are HttpOnly, Secure, and SameSite
- Session expires automatically (TTL)
- Code follows existing conventions
- Documentation is complete
- Local and production environments work correctly
- Mock Authentication: Uses hardcoded users (replace with D1 + password hashing for production)
- No Rate Limiting: Vulnerable to brute-force (add rate limiting for production)
- No CSRF Tokens: Relies only on SameSite cookies (consider CSRF tokens for sensitive operations)
- No Email Verification: Users aren't verified (add for production)
- No Password Reset: Can't reset forgotten passwords
- No Remember Me: Fixed 7-day expiration (could add optional long-lived sessions)
- No Session Revocation: Can't revoke all sessions for a user
- Eventually Consistent: KV is eventually consistent (may see stale data briefly)
CLAUDE.md- Project guidelines and conventionsREADME.md- Project setup instructionswrangler.jsonc- Worker configuration
- Cloudflare KV Documentation
- Workers Sessions Example
- HTTP Cookie Security (MDN)
- React Context API
- OWASP Session Management
// Secure session ID generation
const array = new Uint8Array(16);
crypto.getRandomValues(array);
const sessionId = Array.from(array, byte =>
byte.toString(16).padStart(2, '0')
).join('');
// KV operations with TTL
await env.KV.put(key, value, {
expirationTtl: 604800 // 7 days
});
// Cookie parsing
const cookies = cookieHeader
.split(';')
.reduce((acc, cookie) => {
const [name, value] = cookie.trim().split('=');
acc[name] = decodeURIComponent(value);
return acc;
}, {});
// Secure cookie serialization
const cookie = [
`${name}=${encodeURIComponent(value)}`,
`Max-Age=${maxAge}`,
'HttpOnly',
'Secure',
'SameSite=Lax',
`Path=${path}`
].join('; ');- This example prioritizes simplicity and education over production features
- It demonstrates fundamental session management patterns for Cloudflare Workers
- For production, add password hashing, rate limiting, CSRF protection, and user database
- Consider using established authentication libraries for production applications
- Monitor KV usage and costs if expecting high traffic
{ "kv_namespaces": [ { "binding": "SESSIONS", "id": "xxxxx", "preview_id": "yyyyy" } ] }