Made with Copilot (with humain supervision)
Describe the bug
The OIDC callback handler (OIDCCallback at /oidc_callback) is currently registered as a POST endpoint and attempts to parse a JSON body for the code and state parameters. This does not conform to the OAuth 2.0 (RFC 6749) and OpenID Connect specifications.
Problem details
- The OAuth2/OIDC specification requires that the callback (redirect URI) is called via HTTP GET, with the
code and state included as URL query parameters (not a JSON body, and usually not POST).
- Most providers (Auth0, Google, Azure AD, etc.) will send the user back using a browser redirect with these values in the URL (GET), not as a POST request.
- The current code fails to work with compliant providers unless custom response modes are enabled and code is adapted accordingly.
Relevant code (from api/user/oidc.go):
var loginUser OIDCLoginUser
ok := cosy.BindAndValid(c, &loginUser) // expects JSON body
Specification references:
To Reproduce
- Start OIDC login flow
- Complete authentication in the provider
- See failure upon callback if using a standard OIDC provider
Expected behavior
The callback endpoint should:
- Be registered as a GET route (e.g.,
r.GET("/oidc_callback", OIDCCallback))
- Extract
code and state from query parameters (using c.Query("code") and c.Query("state") in Gin)
- Not expect a JSON body
Additional context
If you want to support POST with form-encoded body (for providers using response_mode=form_post), handle that as a special case—but standard OIDC and OAuth2 providers use GET + query parameters.
Let me know if you'd like suggestions for updated code!
Describe the bug
The OIDC callback handler (
OIDCCallbackat/oidc_callback) is currently registered as a POST endpoint and attempts to parse a JSON body for thecodeandstateparameters. This does not conform to the OAuth 2.0 (RFC 6749) and OpenID Connect specifications.Problem details
codeandstateincluded as URL query parameters (not a JSON body, and usually not POST).Relevant code (from
api/user/oidc.go):Specification references:
To Reproduce
Expected behavior
The callback endpoint should:
r.GET("/oidc_callback", OIDCCallback))codeandstatefrom query parameters (usingc.Query("code")andc.Query("state")in Gin)Additional context
If you want to support POST with form-encoded body (for providers using
response_mode=form_post), handle that as a special case—but standard OIDC and OAuth2 providers use GET + query parameters.Let me know if you'd like suggestions for updated code!