From Extreme Confusion... to Clarity
With so many moving parts â Google Cloud, Clerk, iOS configuration, and my own app â itâs incredibly easy to get lost when trying to understand how OAuth actually works.
After several days of questioning, experimenting, breaking things, and staying persistent, I finally got everything working â a fully functioning demo đ
Even after years of being a developer, this wasnât something that came naturally or instantly. And thatâs exactly why Iâm writing this.
1) Client ID + Client Secret: the introductory business card (and proof of identity)
Think of Google and Clerk like two companies.
- Client ID is your appâs âbusiness cardâ (public identity).
- Client Secret is your appâs âsealed letter / private stampâ (private proof).
When you paste these from Google to into Clerk, youâre basically saying:
âClerk, when my app says âIâm the Google app youâre expectingâ, hereâs the official identity card and the private proof so you can trust itâs really me.â
Why it matters: without this âformal introduction,â Clerk canât confidently talk to Google as your app, and Google wonât know which OAuth app configuration rules to apply.
2) Redirect URL must match: the relay race baton handoff
OAuth is a relay race:
- Your app sends the runner to Google (login screen).
- Google finishes their segment (user authenticates).
- Then Google must hand the baton back to the correct next runner.
That âhandoff pointâ is the Redirect URL.
So the rule is:
The redirect URL Google is allowed to hand the baton to must match what your app/Clerk expects.
Thatâs why you check both dashboards:
- In Google Cloud Console: âThese are the allowed handoff addresses.â
- In Clerk: âThis is the handoff address Iâm expecting.â
If they donât match, Google refuses the handoff (because it could be a security risk).
3) iOS must understand the redirect URL: Google â iOS â Your App
On mobile, the baton doesnât go straight back into your app automatically.
The flow is really:
Google â iOS (system) â Your App
So iOS needs to know:
- âWhen I see a URL that looks like this, which installed app should receive it?â
Thatâs what these do:
-
app.jsonscheme: registers the âspecial address formatâ your app owns (like claiming a mailbox). - Expo Linking: helps your app listen for and parse the incoming redirect so it can resume the login flow.
In human terms:
app.json tells iOS which app owns that URL, and Linking helps your app open the envelope and read what Google sent back.
4) Secure Store: where the baton gets locked up after the race
After OAuth succeeds, you end up with something sensitive stored on the phone (commonly session tokens / refresh tokens, depending on the setup).
Hereâs the key idea:
- A mobile app is not a safe place to keep secrets in plain storage.
- Tokens act like âproof youâre logged in.â
- If stolen, they can be reused like a copied keycard.
So you use Secure Store as the phoneâs built-in safe:
- iOS Keychain / Android Keystore under the hood.
- Encrypted + protected by the OS.
Why it usually needs a rebuild:
- Secure Store is a native capability.
- If your project isnât already including it in the native build (or you change native config), you need a new native build for it to be available properly.
In story form:
Once your app receives the baton (tokens), you donât leave it on the table. You put it in the hotel safe (Secure Store), so nobody can copy it while youâre not looking.
One-line summary
Client ID/Secret = who you are (formal introduction)
Redirect URL = where the baton goes (handoff point)
Scheme/Linking = how iOS routes it (Google â iOS â app)
Secure Store = where you lock the result (tokens in a safe)
Code to followâŚ
Next I will paste the React Native code here⌠please watch this space!
Top comments (1)
I like this explanation.
OAuth documentation often makes me feel like Iâm reading an international treaty written by lawyers, while the actual problem is just âplease send the user back to the right place.â đ
The relay-race analogy makes the whole flow much easier to understand.