SHOPin Logo
Skip to main documentation content

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 successCsrfTokenCleanupInterceptor clears 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

TopicBehaviour
ValidationDecrypt/verify header + cookie, constant-time compare
KeysDedicated CSRF_TOKEN_* secrets, not JWT keys
CleanupCookie cleared on successful mutating response

Related

Back to Authentication · Back to How to work with SHOPin