-
Notifications
You must be signed in to change notification settings - Fork 58
Description
🎯 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
).
- The package should generate and expose the Authorization URL (with PKCE,
// 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
andstate
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 theloginMethod
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