How do you handle CSRF / anti-forgery for a SPA calling an ASP.NET Core API?

ASP.NET Core Authentication Advanced 3–5 Yrs5+ Yrs Scenario 1 min read

Quick Answer

If the SPA authenticates with a bearer token in a header (not a cookie), classic CSRF doesn't apply — the browser doesn't attach the token automatically. If the SPA uses cookie auth, you need anti-forgery: the API issues a token (endpoint or cookie), the SPA reads it and sends it in a header on unsafe requests, and the API validates it. Also set SameSite=Lax/Strict as defence in depth.

It comes down to how the SPA authenticates. If it sends a JWT in the Authorization header, CSRF isn't a concern, because an attacking site can't make the browser attach that header — the browser only auto-sends cookies. If the SPA relies on an auth cookie, then I do need anti-forgery: the API hands the SPA a token, usually via a readable cookie plus an endpoint, and the SPA sends it back in a custom header like X-XSRF-TOKEN on POSTs, which the API validates. On top of either approach I set the auth cookie to SameSite and keep CORS strict.

  • Token-in-header auth (JWT): no anti-forgery token needed. Store the token in memory, not localStorage (XSS), and lock down CORS.
  • Cookie auth SPA: configure AddAntiforgery(o => o.HeaderName = "X-XSRF-TOKEN"); expose the token via a minimal endpoint that also sets a readable XSRF-TOKEN cookie; the SPA (Angular does this by default) echoes it in the header; protect endpoints with [AutoValidateAntiforgeryToken].
  • The BFF (backend-for-frontend) pattern keeps tokens server-side in a cookie and centralises this.