-
Notifications
You must be signed in to change notification settings - Fork 672
Description
Feature Request
Plugin
@capacitor/browser
Description
The Browser plugin opens URLs using SFSafariViewController on iOS and Chrome Custom Tabs on Android. The plugin's own README notes that SFSafariViewController is "compliant with leading OAuth service in-app-browser requirements," and this is broadly true — both primitives do share cookies and session data with the system browser, which satisfies many IdP requirements.
However, they are still not the right tool for structured OAuth/OIDC callback flows, for a different reason: neither primitive provides a way to intercept and return the redirect URI back to the calling app as a resolved value. When an IdP redirects to a custom URL scheme (e.g. myapp://auth/callback?code=...) or a universal link at the end of an auth flow, SFSafariViewController has no mechanism to catch that redirect and return it to the app.
The result is that the browser either stalls on a blank page or the appUrlOpen event fires inconsistently, depending on how the redirect URI is configured. There is no clean, reliable way to close the browser and return the authorization code or token to the calling code as a promise resolution.
That said, it's not impossible to make SSO work in Capacitor, but the proper platform APIs aren't being exposed.
Both platforms provide dedicated APIs designed specifically for this use case, and it would be valuable to expose them through the Browser plugin or as a new dedicated method.
Platform(s)
- iOS
- Android
Preferred Solution
Expose platform authentication session APIs, either as a new method on the existing Browser plugin or as a separate openAuthSession surface:
iOS: ASWebAuthenticationSession
This is the current recommended API (available since iOS 12), replacing the deprecated SFAuthenticationSession. It is purpose-built for OAuth and SSO flows: it opens a browser context, monitors for a redirect to the specified callback URL scheme, and returns the full callback URL to the app as a completion handler.
It presents an explicit consent prompt to the user before sharing any cookies with the identity provider session, and supports an prefersEphemeralWebBrowserSession option to use a private, non-shared session instead (which suppresses the consent prompt and is appropriate for flows that don't need SSO cookie persistence).
Android: Chrome Custom Tabs + redirect intent handling
Android does not have a direct 1:1 equivalent to ASWebAuthenticationSession. The recommended approach is the existing Custom Tabs implementation, but augmented with proper deep link / intent filter handling so the app can receive the OAuth redirect URI when the IdP redirects back. This requires the app to register an intent filter for the callback scheme and the plugin to wire up the round-trip correctly. The AppAuth for Android library documents this pattern well and would be a useful reference implementation.
A minimal API addition could look like:
const result = await Browser.openAuthSession({
url: 'https://idp.example.com/authorize?...',
callbackURLScheme: 'myapp',
// iOS only: omit to default to shared session with consent prompt
prefersEphemeralSession: true,
});
// result.callbackURL contains the full redirect URI the IdP sent back
// e.g. "myapp://auth/callback?code=abc123&state=xyz"On iOS this maps directly to ASWebAuthenticationSession. On Android it would open a Custom Tab and resolve the promise when the app receives the matching intent via the registered deep link.
Alternatives
- The
@capacitor/communityecosystem hascapacitor-app-auth, but it is not officially maintained and tends to lag behind platform API changes. - Manually wiring up
App.addListener('appUrlOpen', ...)alongsideBrowser.open()is a workaround, but it is unreliable — the browser does not close itself when the redirect fires, and sequencing the listener with the browser open/close lifecycle is fragile and error-prone (see Capacitor Browser - Universal link callback not triggered during auth flow #628).
Additional Context
- Apple docs: ASWebAuthenticationSession
- The deprecated
SFAuthenticationSession(iOS 11 only) is the direct predecessor toASWebAuthenticationSessionand illustrates the intended pattern - AppAuth for Android pattern: https://github.com/openid/AppAuth-Android
- Previous issue about this, that was closed: Single Sign-on (SSO) Child Browser Flow capacitor#1948