Skip to content

💡 [REQUEST] - Add loginMethod: 'native' to support RFC 8252 (in-app/external browser + deep‑link callback) #223

@Jorgagu

Description

@Jorgagu

🎯 Add loginMethod: 'native' to support RFC 8252 (in-app/external browser + deep-link callback)

Description

RFC 8252 ("OAuth 2.0 for Native Apps", Oct 2017) mandates that native apps utilize external user-agents (system browser or in-app browser tabs) and avoid embedded WebViews, using deep-link or loopback callbacks with PKCE and state validation.

Currently, the package uses passive detection of ?code=... in window.location after returning from the Authorization Flow. This supports classic browser-based redirects, but does not make explicit how to integrate with native apps using deep-links.

Additionally, there is currently no built-in way to distinguish or configure the authorization flow for native apps. The loginMethod option only supports 'redirect' and 'popup' modes for web scenarios. There is no 'native' mode to facilitate integration with native or hybrid app patterns as described by RFC 8252.

Proposal

  • Introduce a new config option:
// TypeScript: extend AuthConfig type
// Add support for 'native' login method

type AuthConfig = {
  /* existing fields */
  loginMethod?: 'redirect' | 'popup' | 'native';
  onLoginUrlReady?: (url: string) => void;
};
  • When loginMethod === 'native':

    • The package should generate and expose the Authorization URL (with PKCE, state, etc.) via a callback or function (e.g. onLoginUrlReady).
    • The developer is responsible for opening this URL using an in-app browser, system browser, or similar user-agent.
    • The OAuth server must be configured to use the app's custom scheme as the redirect URI (e.g. myapp://oauth/callback).
// Example OAuth redirect
// myapp://oauth/callback?code=...&state=...
  • When the browser receives the OAuth callback, the OS deep-link handler navigates back into the app and routes to the appropriate screen (typically your React/SPA root or a dedicated route).
  • From this point, the package can function as usual: the library will passively detect the code and state parameters in the URL (now provided via deep-link navigation) and handle the token exchange as in a classic browser-based flow.

In other words: for native usage, the only adaptation required is that the deep-link navigation must land on a route handled by the React app where the package is active. No explicit handleCallback() is needed as long as the package can see the query params in the URL when the app resumes or navigates.

Why this matters

  • Embedded WebViews are insecure — they allow credential harvesting and break single sign-on.
  • Native apps (including React Native, Capacitor, Tauri, hybrid, etc.) need full control over how and when the browser opens, and how callbacks are intercepted.
  • This proposal leverages the package's existing logic for query param detection, ensuring that only the Authorization URL generation and opening method need to be managed differently in native scenarios.
  • The new loginMethod: 'native' makes the integration explicit and developer-friendly for mobile and hybrid apps.

Implementation suggestions

  • Add support for the 'native' value to the loginMethod option.
  • Expose the authorization URL for native usage without automatically redirecting.
  • Document that the developer must ensure the deep-link lands on a route where the package is loaded and can observe the URL.
  • No need to change callback handling logic; passive detection remains sufficient.

Summary

Add a loginMethod: 'native' mode to:

  • Generate PKCE + state-protected authorization URL
  • Let the developer open the URL in any browser context (system or in-app)
  • Use the OS deep-link handler to return to the app, where the package will resume normal operation as long as it can detect the query params in the URL
  • Fully comply with RFC 8252 for mobile and native OAuth flows

Happy to assist with API design or PR implementation 👍

Basic Example

Example usage

const auth = new AuthService({
  clientId,
  provider: authEndpoint,
  redirectUri: 'com.myapp://oauth/callback',
  scopes: ['openid','profile'],
  loginMethod: 'native',
  onLoginUrlReady: (url) => {
    // Developer decides how to open browser
    openInAppBrowser(url);
  },
});

// After user authenticates, the OAuth server redirects to:
// myapp://oauth/callback?code=...&state=...
// The OS deep-link handler opens your app at that route.
// The package detects code/state in the URL and continues as normal.

Drawbacks

This proposal is not a breaking change and is fully backward compatible. The existing web behaviors (loginMethod: 'redirect' and 'popup') remain unchanged, so there is no impact or risk to current applications using the package.

Unresolved questions

No response

Implementation PR

No response

Reference Issues

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions