Skip to Content
Ranlanka CRM documentation — pre-release, subject to change.
DebuggingCSRF & Auth Errors

CSRF & Auth Errors

These were the hardest class of bug to track down when first standing up the API behind a real domain — each fix exposed the next, deeper layer of the same underlying issue.

Bare 403 on every mutating request, no JSON body

Symptom: POST/PUT/PATCH/DELETE all return a bare 403 with no response body, in both local dev and production. GET requests and login work fine.

Cause: Spring Security’s default CSRF token handler only writes the CSRF cookie into the response when something explicitly reads the CSRF token attribute mid-request. Server-rendered form views do this automatically; a pure JSON API with no view layer never triggers it — so the cookie is never set, the frontend has nothing to attach as a header, and every mutating request is rejected before it reaches a controller.

Fix: add a filter that forces eager token resolution on every request — reads the CSRF token attribute and calls its getter, unconditionally. This is the standard documented workaround for CSRF on a pure-API (non-template) Spring Security setup.

Symptom: DevTools shows the CSRF cookie exists, but the failing request’s actual Cookie header (in the Network tab) doesn’t include it.

Cause: the frontend and API are on different subdomains. A cookie set with no explicit Domain attribute is scoped only to the exact hostname that set it — JavaScript running on a different subdomain can never read it via document.cookie, regardless of SameSite settings. This is a browser cookie-scoping rule, not a CSRF or CORS setting.

Fix: set an explicit Domain attribute on the CSRF cookie so it’s shared across subdomains of the same registrable domain, via a configurable property — left empty for local dev (where both sides run on localhost and no domain scoping is needed).

Symptom: after fixing the above, login itself starts throwing a 500 with an “invalid domain” exception.

Cause: the cookie-domain value had a leading dot (the old convention for “match this domain and all subdomains”). Modern strict cookie processors enforce RFC 6265, which does not allow a leading dot at all — it throws rather than silently stripping it. Under RFC 6265, a domain with no leading dot already implies “this domain and all its subdomains” — the dot isn’t just unnecessary, it’s invalid.

Fix: remove the leading dot from the cookie-domain value.

This exception only surfaces at runtime, on the first request that actually tries to save a CSRF token cookie (e.g. during login) — it does not fail at application startup. Always test an actual login end-to-end after changing this kind of config, not just a health check.

Last updated on