Auth in the App
Magic codes work in-webview; OAuth has to open externally. Here's why and how.
Sign-in works differently inside the native shells than it does on the web, for one specific reason: Google actively blocks OAuth flows from completing inside an embedded web view. Everything else about how the shells handle auth follows from that one constraint.
Magic codes work exactly as they do on the web
A magic code, the six-digit number you enter after requesting a sign-in, works fine inside the shell's embedded web view with no special handling at all. There's no redirect involved, no external identity provider, just a form submission the web view handles like any other page. This is different from a magic link, which would need to reopen the app from an email client; codes sidestep that problem entirely, which is part of why the kit uses codes rather than links in the first place.
Social sign-in has to leave the web view
Google and Apple sign-in are different. Google in particular treats an embedded web view as
untrustworthy for OAuth and blocks the flow outright, so both shells open social sign-in
externally instead of inside the app's own web view: ASWebAuthenticationSession on iOS,
Chrome Custom Tabs on Android. The user completes sign-in in that external, trusted browser
context, and the shell receives the resulting session back and hands it to the web view.
This is driven by the path configuration Rails serves at /configurations/ios.json and
/configurations/android.json: every /auth/ route is marked external, which tells each shell
to intercept navigation to that path rather than load it in the embedded web view. Because this
routing rule lives in a Rails-served configuration file rather than being compiled into the app,
changing which paths open externally doesn't need a new build or a new App Review.
Apple sign-in is iOS-only in the shells
The server gates the Sign in with Apple button on hotwire_native_android?, so it doesn't render
inside the Android shell at all. Apple only requires SIWA to be offered on iOS; showing it on
Android would be both unnecessary and slightly odd for an Android user.
What this means if you add a new OAuth provider
Any new social sign-in provider needs the same treatment: its /auth/:provider path has to be
marked external in the path configuration, or the shell will try to load the provider's
consent screen inside the embedded web view and it may silently fail to complete, the same failure
mode Google's blocking produces.
Next
See how the shells handle the one thing that can't route through a webview at all, paid subscriptions: In-App Purchases.