Skip to content

[EPIC] httpOnly Cookie Authentication MigrationΒ #217

@kevalyq

Description

@kevalyq

🎯 Vision

Migrate Sanctum authentication to hybrid approach supporting both httpOnly cookie-based (Web/PWA) and Bearer token authentication (Native mobile) for enhanced security and platform flexibility.


βœ… STATUS: COMPLETE (100%)

Backend implementation: βœ… Fully Complete (25.11.2025)
Frontend implementation: βœ… Fully Complete (25.11.2025)


πŸ“‹ Sub-Issues & Work Plan

Backend Implementation Phases

Frontend Implementation (SecPal/frontend)

Frontend Epic: SecPal/frontend#208 βœ… Complete (23.11.2025)

  • frontend#210 localStorage Removal & httpOnly Cookie Migration βœ… Complete
  • frontend#211 CSRF Token Handling & Request Interceptor βœ… Complete
  • frontend#212 Integration Testing & Documentation βœ… Complete
  • frontend#227 CSRF Integration for secretApi βœ… Complete

Note: Issues frontend#224, #225, #226 were created after implementation was complete under Epic #208 and have been closed as duplicates.


🎯 Success Criteria

  • βœ… CSRF Protection: /sanctum/csrf-cookie endpoint accessible
  • βœ… httpOnly Cookies: Session cookies configured securely
  • βœ… Sanctum Stateful: Frontend domain whitelisted in SANCTUM_STATEFUL_DOMAINS
  • βœ… CORS Configured: supports_credentials: true for authenticated requests
  • βœ… Session Driver: Using database driver with secure settings
  • βœ… Documentation: API docs (docs/guides/sanctum-spa-auth.md) and production deployment guide complete
  • βœ… All Tests Pass: 38 backend tests, 87 assertions + 28 frontend integration tests
  • βœ… Hybrid Authentication: Cookie-based (Web) + Bearer tokens (Mobile) documented

πŸ”’ Security Improvements

Before (Token-based):

  • ❌ Token stored in localStorage (XSS-vulnerable)
  • ❌ Token accessible via JavaScript
  • ❌ Manual token management required
  • ❌ No built-in expiration enforcement

After (httpOnly Cookies for Web/PWA):

  • βœ… Token in httpOnly cookie (XSS-protected)
  • βœ… Browser handles token automatically
  • βœ… CSRF protection via Sanctum
  • βœ… Server-side expiration control
  • βœ… Secure + SameSite flags

Maintained (Bearer Tokens for Native Apps):

  • βœ… Simple API integration for mobile
  • βœ… No CORS complexity
  • βœ… Platform secure storage (Keychain/Keystore)
  • βœ… Future-proof for Android/iOS apps

πŸ“š Technical Architecture

Hybrid Authentication Strategy

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Client Type              β”‚ Auth Method          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Web SPA (Vite)           β”‚ httpOnly Cookies βœ…  β”‚
β”‚ PWA (Browser)            β”‚ httpOnly Cookies βœ…  β”‚
β”‚ Android App (Native)     β”‚ Bearer Token βœ…      β”‚
β”‚ iOS App (Native)         β”‚ Bearer Token βœ…      β”‚
β”‚ Desktop App (Tauri)      β”‚ Bearer Token βœ…      β”‚
β”‚ CLI / Scripts            β”‚ Bearer Token βœ…      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Single Guard Configuration:

// routes/api.php - Accepts BOTH authentication methods
Route::middleware(['auth:sanctum'])->group(function () {
    // Works with Cookie-based (Web/PWA) OR Bearer token (Mobile/API)
});

Configuration Changes

Sanctum Configuration:

// config/sanctum.php
'stateful' => explode(',', env(
    'SANCTUM_STATEFUL_DOMAINS',
    'localhost,localhost:5173,127.0.0.1,127.0.0.1:5173,::1'
)),

CORS Configuration:

// config/cors.php
'supports_credentials' => true,
'allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', 'http://localhost:5173')),

Session Configuration:

// config/session.php
'driver' => env('SESSION_DRIVER', 'database'),
'http_only' => true,
'secure' => env('SESSION_SECURE_COOKIE', false), // true in production
'same_site' => 'lax',

API Flow (Web/PWA - Cookie-based)

1. Frontend: GET /sanctum/csrf-cookie
   Response: Set-Cookie: XSRF-TOKEN=...

2. Frontend: POST /v1/auth/token (credentials: 'include')
   Headers: X-XSRF-TOKEN: <token>
   Response: Set-Cookie: secpal-session=... (httpOnly)
   Body: { user: {...}, token: "..." }

3. Frontend: Subsequent requests include cookies automatically
   Headers: Cookie: secpal-session=...
           X-XSRF-TOKEN: <token>

API Flow (Mobile - Token-based)

1. Mobile App: POST /v1/auth/token
   Headers: Content-Type: application/json
   Body: { email, password }
   Response: { user: {...}, token: "1|abc123..." }

2. Store token in secure storage (Keychain/Keystore)

3. Subsequent requests:
   Headers: Authorization: Bearer 1|abc123...

πŸ”— Related Issues

Frontend (SecPal/frontend):

  • frontend#205 βœ… Complete - Duplicate Epic (closed, work done under Backend PR-3: Tests & API Documentation UpdateΒ #208)
  • frontend#208 βœ… Complete - Epic: httpOnly Cookie Authentication Migration
  • frontend#210 βœ… Complete - localStorage Removal
  • frontend#211 βœ… Complete - CSRF Token Handling
  • frontend#212 βœ… Complete - Integration Testing & Documentation
  • frontend#227 βœ… Complete - CSRF Integration for secretApi

Backend (this repo):


πŸ“Š Implementation Timeline

Phase 1 (Complete): CSRF Token Endpoint - Issue #210 βœ… Done (23.11.2025)
Phase 2 (Complete): Sanctum Stateful Configuration - #218 βœ… Done (25.11.2025)
Phase 3 (Complete): Integration Testing & Documentation - #219 βœ… Done (25.11.2025)

Backend Status: βœ… Complete (100%)
Frontend Status: βœ… Complete (100%)
Total Effort: 4 days (cross-repo)
Completion Date: 25 November 2025


βœ… Completed Deliverables

Documentation

  • βœ… docs/guides/sanctum-spa-auth.md (571 lines) - Complete SPA authentication guide
  • βœ… docs/guides/production-deployment.md (600+ lines) - Production deployment guide
  • βœ… Frontend: docs/authentication-migration.md (600+ lines) - Developer migration guide

Tests

  • βœ… Backend: 38 tests, 87 assertions (all passing)
  • βœ… Frontend: 28 integration tests (all passing)
  • βœ… Total: 677 frontend tests passing

Configuration

  • βœ… config/sanctum.php - Stateful domains configured
  • βœ… config/cors.php - Credentials support enabled
  • βœ… config/session.php - httpOnly, SameSite=lax configured
  • βœ… .env.example - Fully documented with all variables

Quality Assurance

  • βœ… Backend: PHPStan Level Max: 0 errors
  • βœ… Backend: Laravel Pint PSR-12: 0 violations
  • βœ… Frontend: TypeScript strict mode: Clean
  • βœ… Frontend: ESLint: Clean
  • βœ… CHANGELOG.md updated (both repos)

πŸ“ Testing Strategy

Backend:

  • Feature test: CSRF token endpoint accessible βœ…
  • Feature test: Session configuration correct βœ…
  • Feature test: Sanctum stateful domains configured βœ…
  • Feature test: CORS credentials support βœ…
  • Integration test: Login with credentials flow βœ…
  • Integration test: Authenticated requests work βœ…
  • Integration test: CSRF validation enforced βœ…
  • Integration test: Logout clears session βœ…
  • Integration test: Cross-origin requests work βœ…
  • Security test: httpOnly flag set correctly βœ…
  • Security test: Secure flag set in production βœ…
  • Integration test: Concurrent device sessions βœ…
  • Integration test: CORS preflight requests βœ…

Frontend:

  • Integration test: Login flow with CSRF and cookies βœ…
  • Integration test: Authenticated requests with cookies βœ…
  • Integration test: Logout clears session βœ…
  • Integration test: No token in localStorage βœ…
  • Integration test: CSRF token in mutating requests βœ…
  • Integration test: 419 retry with fresh token βœ…

πŸ“– References


Type: Epic
Priority: High (Security Feature)
Target Milestone: v0.3.0
Backend Status: βœ… Complete (100%)
Frontend Status: βœ… Complete (100%)
Completion Date: 25 November 2025

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    βœ… Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions