How to Add Authentication to Your Expo App (And the Redirect Trap That Breaks It in Production)

DavidDavid August 12, 2026 9 min read
A brass door key resting on a clean concrete surface in soft directional daylight
Original image, App Store Launch Club

Pick the Simplest Auth Your App Can Live With

Authentication is where a lot of first apps stall, and usually because the developer picked a harder option than the app needed. Before writing any code, decide honestly what the account is actually for. If it exists only so a user's data follows them across devices, you need far less than you think.

Auth options, from least to most complexity

ApproachGood whenWhat it costs you
No accounts at all, local storage onlyThe app is a personal tool and data never needs to move devicesNo sync, no recovery if the device is lost
Email link or one-time codeYou want accounts without password handlingDepends on an email provider actually delivering reliably
Email and password via a managed backendYou need standard accounts and a familiar flowPassword reset, validation, and account recovery screens
Social sign-in through OAuth providersYour users expect it or friction at signup is killing youPer-provider configuration, redirect URIs, and store review requirements

Store the Token in Encrypted Storage

Once a user signs in, you are holding a credential, and where you put it matters. Expo provides expo-secure-store, which writes to the platform's encrypted storage on iOS and Android. That is where a session token belongs. Plain key-value storage is fine for a theme preference and wrong for anything that grants access to an account.

The important detail people miss is that secure storage is a native capability. It does not exist on web, so if your Expo app also runs in a browser you need a separate path there, typically browser storage or a secure cookie set by your own backend. Writing the storage layer as one small helper that branches on platform, rather than sprinkling storage calls through your screens, saves a lot of pain later.

The Redirect Trap

This is the failure that costs people a full day, usually on the morning of their first TestFlight build. OAuth needs a redirect URI - the address the provider sends the user back to after they approve. In Expo, that address is not the same in every environment.

Running inside Expo Go during development, the redirect resolves to an Expo development URL. In a standalone or bare native build, it resolves to your app's own scheme, in the shape of your application identifier followed by a redirect path. Those are different strings, and an OAuth provider only accepts redirect URIs you have registered with it in advance.

  1. Register every redirect URI you will use, not just the development one. The provider console needs the standalone build's URI added before the build exists, or the first real test fails.
  2. Set your app's scheme deliberately in your app config and keep it consistent. The native redirect is derived from your identifier, so an identifier change is also an auth change.
  3. Test auth in a real build, not only in Expo Go. This is the single highest-value test in the whole feature, and it is the one almost everyone postpones.
  4. Test it again after any change to your bundle identifier, package name, or scheme, because all three feed the redirect.

Gate Your Screens, Not Just Your Data

Once sign-in works, the app needs to know which screens a signed-out user can reach. Keep the session in one place - a context or provider that loads the stored token on launch and exposes a single signed-in flag - and let your navigation read from that. Scattering checks through individual screens produces a flow where a signed-out user can still deep link into an authenticated screen.

Handle the loading state explicitly. Reading the token from secure storage is asynchronous, so on launch there is a brief moment where you do not yet know whether the user is signed in. Rendering the signed-out screen during that gap is what causes the flash of a login screen that then disappears, which users read as a bug even when it is not.

Before You Submit to the Stores

Both stores have review expectations around accounts, and they are a common rejection reason for apps that otherwise pass. Check the current review guidelines yourself rather than relying on a summary, including this one, because these requirements are revised over time.

  • Provide working demo account credentials in your review notes if any part of the app is behind a login. A reviewer who cannot sign in will reject the build.
  • Do not require an account for functionality that does not need one. Forcing registration to see content that could be shown anonymously is a known rejection trigger.
  • If you offer third-party social sign-in, check the current requirements around offering an equivalent private or alternative sign-in option, since these rules have changed before.
  • Make sure account deletion is reachable from inside the app if you allow account creation, and confirm the current requirement rather than assuming.

Build the Auth You Need, Then Ship

Pick one sign-in method, put the token in secure storage behind a single helper, gate your navigation from one session source, and then make a standalone build and test the whole flow on a real device before you tell anyone the beta is ready. That order is what keeps auth from becoming the reason your launch slips by three weeks.

Free app-building tips, straight to your inbox

Short, practical drops on app ideas, validating fast, store listings, and passing app review. No spam, unsubscribe anytime.

Frequently asked questions

What is the easiest way to add authentication to an Expo app?

The easiest working auth is the one with the fewest moving parts your app can survive on. For many first apps that is an email link or one-time code rather than passwords or social sign-in, because every additional provider adds a redirect configuration that can break between development and production.

Where should I store the auth token in an Expo app?

In encrypted device storage via expo-secure-store on iOS and Android, not in plain key-value storage. Secure store is native only, so if your app also runs on web you need a separate path there such as browser storage or a secure cookie set by your backend. Wrap both behind one small helper.

Why does my Expo OAuth login work in development but fail in a real build?

Because the redirect URI is different. Inside Expo Go it resolves to an Expo development URL, while a standalone build uses your app's own scheme derived from its identifier. OAuth providers only accept redirect URIs you registered in advance, so the standalone one has to be added to the provider before the first real build is tested.

Do I need a client secret for OAuth in a mobile app?

No, and you should never ship one. Anything in the app bundle can be read by anyone who downloads it, so native apps are treated as public clients and the standard mobile flow is designed to work without a secret. If a setup guide tells you to embed one, that guide is for a server, not an app.

Will Apple or Google reject my app for how I handle sign-in?

It is a common rejection area, so check the current review guidelines directly rather than any summary. The recurring themes are providing working demo credentials in your review notes, not forcing an account for functionality that does not need one, and meeting the current requirements around alternative sign-in options and in-app account deletion.

Last reviewed by David on August 12, 2026

David

Written by

David

Founder and app builder

Keep reading

App StoreLaunch

App Store Phased Release: How the 7-Day Rollout Works, How to Pause It, and When to Skip It

App Store phased release rolls a version update out to a random sample of users with automatic updates on over 7 days: 1 percent on day one, then 2, 5, 10, 20, 50 and 100. You can pause it for up to 30 days in total, or release to everyone with one button. Here is exactly what Apple says it does, what it does not do, and how I decide when an Expo app update should use it.

David 8 min
Read article
App StoreLaunch

App Store Pre-Order: How to Set It Up for Your First Expo App (and When It Is Worth It)

An App Store pre-order publishes your product page before your release date so people can order the app, and on launch day it downloads to their device automatically. Apple only publishes the pre-order after the build has passed App Review, the release date has to sit two to 180 days out for a brand-new app, and you have to release the version manually. Here is how to set it up in App Store Connect for an Expo app, what Apple charges and when, and the three questions I use to decide whether a pre-order is worth the wait.

David 9 min
Read article

Ready to build it yourself?

Join App Store Launch Club, the #1 community for building and launching apps, for $9/month.

← Back to the blog