CSRF protection
Authentication · CSRF protection
It is important to read the sections Why this shape and Reference example and production readiness on Authentication before relying on this page. They explain why the default BFF-centred pattern exists, how you can extend or replace it, and what the reference implementation does and does not promise for production.
Use this page when you need to know how mutating BFF requests carry CSRF: a value in a header and the same value in a cookie. CsrfGuard calls csrf-token.service.ts, which decrypts and verifies both copies, then compares them with timingSafeEqual. Issuance and encryption use csrf-token-encryption.service.ts. Store CSRF_TOKEN_* secrets separately from JWT signing keys (Config & constants, CSRF_TOKEN_HEADER_NAME).
Implementation
- Double-submit — The same logical token must appear in the header (name from constants) and in the cookie the browser sends.
- Generation — Strong random material, then sign and encrypt for transport.
- Single-use on success —
CsrfTokenCleanupInterceptorclears the CSRF cookie after successful responses so the next mutation needs a new token; failed requests keep the token so the client can retry.
Protected operations
Login, register, logout, and other mutating BFF routes (cart, orders, customer updates, and similar) require CSRF. From the presentation app: call GET /csrf/token, then send the header on POST, PUT, or DELETE. If you receive 403, fetch a new token and retry once.
Summary
| Topic | Behaviour |
|---|---|
| Validation | Decrypt/verify header + cookie, constant-time compare |
| Keys | Dedicated CSRF_TOKEN_* secrets, not JWT keys |
| Cleanup | Cookie cleared on successful mutating response |