[GH-ISSUE #1563] OIDC callback endpoint should use GET and query parameters, not POST with JSON body #3094

Open
opened 2026-02-27 12:31:10 +03:00 by kerem · 0 comments
Owner

Originally created by @Tom60chat on GitHub (Feb 16, 2026).
Original GitHub issue: https://github.com/0xJacky/nginx-ui/issues/1563

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

  1. Start OIDC login flow
  2. Complete authentication in the provider
  3. 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!

Originally created by @Tom60chat on GitHub (Feb 16, 2026). Original GitHub issue: https://github.com/0xJacky/nginx-ui/issues/1563 > 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`): ```go var loginUser OIDCLoginUser ok := cosy.BindAndValid(c, &loginUser) // expects JSON body ``` #### Specification references: - [OAuth 2.0 RFC 6749 Section 4.1.2](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2) - [OpenID Connect Core Spec: Authorization Code Flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth) ### To Reproduce 1. Start OIDC login flow 2. Complete authentication in the provider 3. 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!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/nginx-ui#3094
No description provided.