Skip to content

OAuth consent flow (frontend) #7034

@Zaimwa9

Description

@Zaimwa9

Context

When an OAuth client redirects a user to the authorize endpoint, the user may not be logged in.
The login and consent flow should all happen on the frontend domain app.flagsmith.com to avoid cross-domain redirect issues between the frontend and the API.

After login (or immediately if already logged in), the user is redirected to a consent screen showing which application is requesting access and what scopes it wants.

To do

  • New authorize page on the frontend: app.flagsmith.com/oauth/authorize?client_id=...&scope=...&...

Login redirect:

  • If the user is not logged in:
    • Redirect to app.flagsmith.com/login?returnTo=/oauth/authorize?...
    • The login page reads the returnTo query parameter
    • After successful login, redirect to the returnTo URL
  • If the user is already logged in:
    • Go straight to the consent screen (no login step)
  • All existing login methods must work (email/password, Google, GitHub, SAML)
  • Security: validate that returnTo is an internal path (starts with /) and not an external URL

Consent screen:

  • New page app.flagsmith.com/oauth/authorize
  • The page receives OAuth parameters from the query string (client_id, scope, redirect_uri, code_challenge, etc.)
  • Display:
    • Application name (from DOT's Application model)
    • Requested scopes in plain language
    • Unverified/DCR-registered apps should be clearly labelled as such
    • "Allow" and "Deny" buttons
  • On "Allow": call the API to create the authorization code (using DOT's Authorization.create_authorization_response()), then redirect to the client's redirect_uri with the authorization code
  • On "Deny": redirect to the client's redirect_uri with error=access_denied

Definition of done

  • Login page handles returnTo parameter
  • After login, user is redirected to the consent page with all original query parameters preserved
  • If already logged in, the consent screen is shown directly
  • All login methods work (email/password, Google, GitHub, SAML)
  • returnTo is validated as an internal path — external URLs rejected
  • Consent screen shows app name and requested scopes
  • DCR-registered apps labelled as unverified
  • "Allow" issues an authorization code and redirects to the client callback
  • "Deny" redirects with error=access_denied
  • PKCE validation works end-to-end
  • Full flow works: login → consent → authorization code → token exchange

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions