-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Description
📦 Sub-Issue of Epic #217
Part of: #217 (httpOnly Cookie Authentication Migration)
Priority: High
Area: Backend, Configuration, Security
Repository: api
Goal
Configure Laravel Sanctum for stateful SPA authentication with httpOnly cookies, including SANCTUM_STATEFUL_DOMAINS whitelist and CORS configuration to support credentials.
Acceptance Criteria
Sanctum Configuration
-
SANCTUM_STATEFUL_DOMAINSconfigured in.envand.env.example - Frontend domains whitelisted (localhost:5173, production domain)
-
config/sanctum.phpproperly configured for stateful mode - Sanctum middleware enabled for API routes
CORS Configuration
-
supports_credentialsset totrueinconfig/cors.php -
allowed_originsincludes frontend URL from.env -
allowed_headersincludesX-XSRF-TOKEN -
exposed_headersconfigured if needed
Session Configuration
- Session driver uses
cookie(already set in Backend PR-2: CSRF Token Endpoint & Security Hardening #210) -
SESSION_DOMAINconfigured for cross-subdomain support - Session cookies work across frontend/backend
Environment Variables
-
.env.exampleupdated with new variables:SANCTUM_STATEFUL_DOMAINS=localhost,localhost:5173,127.0.0.1:5173 FRONTEND_URL=http://localhost:5173 SESSION_DOMAIN=localhost
Testing
- Feature test: Stateful authentication flow works
- Feature test: CORS credentials accepted
- Feature test: Frontend domain in whitelist
- Feature test: Non-whitelisted domains rejected
- PHPStan passes
- Pint passes
- All existing auth tests pass
Documentation
-
docs/guides/sanctum-spa-auth.mdcreated -
.env.examplehas clear comments - CHANGELOG.md updated
Implementation Details
Files to Modify
Configuration:
// config/sanctum.php
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'localhost,localhost:5173,127.0.0.1,127.0.0.1:5173,::1'
)),
'middleware' => [
'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class,
'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class,
],CORS:
// config/cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:5173')],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true, // CRITICAL!Environment:
# .env.example
SANCTUM_STATEFUL_DOMAINS=localhost,localhost:5173,127.0.0.1:5173
FRONTEND_URL=http://localhost:5173
SESSION_DOMAIN=localhost
SESSION_SECURE_COOKIE=false # true in productionTesting Strategy
# Test CSRF cookie works
curl -X GET http://api.secpal.test/sanctum/csrf-cookie -i
# Test login with credentials
curl -X POST http://api.secpal.test/v1/auth/token \
-H "Content-Type: application/json" \
-H "X-XSRF-TOKEN: <token>" \
-d '{"email":"test@example.com","password":"password"}' \
--cookie-jar cookies.txt
# Test authenticated request
curl -X GET http://api.secpal.test/v1/user \
-H "X-XSRF-TOKEN: <token>" \
--cookie cookies.txtDependencies
- Depends on: Backend PR-2: CSRF Token Endpoint & Security Hardening #210 ✅ Complete (CSRF endpoint exists)
- Blocks: [EPIC] Migrate to httpOnly Cookie Authentication frontend#205 (Frontend needs backend ready)
- Part of: Epic [EPIC] httpOnly Cookie Authentication Migration #217
Security Considerations
⚠️ Never disable CSRF protection in production⚠️ Use HTTPS in production (SESSION_SECURE_COOKIE=true)⚠️ RestrictSANCTUM_STATEFUL_DOMAINSto known domains only⚠️ Never useallowed_origins = ['*']withsupports_credentials = true
Breaking Changes
- Token-based authentication endpoints remain functional
- New cookie-based authentication flow added alongside
- Frontend needs to migrate to new flow
Migration Path:
- Backend deployed with both auth methods working
- Frontend migrates to cookie-based auth
- (Future) Deprecate token-based auth
References
- Laravel Sanctum SPA Auth
- CORS Credentials
- Epic: [EPIC] httpOnly Cookie Authentication Migration #217
Type: Sub-Issue
Priority: High
Estimated Effort: 1-2 days
Sprint: Current
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
✅ Done