OIDC login via Discourse iOS app occasionally fails with csrf_detected on callback

One additional data point that may help confirm this is a deterministic WKWebView limitation rather than intermittent behaviour.

By correlating nginx access logs across multiple failures, I’ve found that the same OIDC state value is repeatedly reused by the in-app browser when users retry login.

Example (sanitised):
• Same state hash seen 14 times
• All requests from:

Snapchat/13.77.0.51 (like Safari…, panda)

• Spread across ~1 hour of repeated login attempts
• Each attempt results in:

/auth/oidc/callback → /auth/failure?message=csrf_detected

This strongly suggests that:
• the browser never successfully stores the session cookie containing the original state
• each retry reuses the same stale state parameter
• Discourse is therefore correctly rejecting the callback every time

In contrast, when the same user opens the link in Safari, a new state is generated and the login succeeds immediately.

So this appears to be a fully deterministic failure mode in certain iOS in-app browsers rather than a timing or race condition.

From Discourse’s perspective, the CSRF protection is behaving exactly as intended - the browser environment simply cannot maintain the required session continuity.

I think this further supports that:
• this is not something a theme component or client JS can mitigate
• and that the only reliable handling is server-side messaging and documentation

Posting in case this data point is useful for confirming expected behaviour.