Google sign-in

A Google button beside the emailed sign-in code. Off until the owner turns it on.

What it is. A second way into your app, beside the emailed code. Whichever one a person uses, it's the same account: Gemmein matches Google's own verified email to a person who already signed in by email, or creates one the first time.

What it does.

  • Turns on per environment. Off by default. Turn it on from Settings → Connections in the dashboard, or: in Development, your AI's set_google_signin or npx gemmein apps signin google on|off, both at once; in Live, your AI's request_google_signin_switch or npx gemmein apps signin google on|off --env live, both asking for your approval in the browser. Going live copies Development's switch, and its own Google client if one is set, to Live too, one time only; after that, Live's own switch moves only through its own browser approval.
  • Gemmein's client, or your own. Every app shares Gemmein's own Google client by default: your customers see "Gemmein" on Google's own screen. Paste your own Google Cloud project's client ID and secret on Settings → Connections, in Developer mode, to show your own name instead; leave Gemmein's in place unless you need that. Once the app is live, saving or removing your own client asks for the code Gemmein emails, and your authenticator code too if you have one — the same as any other change to how the business runs.
  • What customers see. On the web, a Google button opens Google's own consent screen in a redirect and lands back in your app signed in. On a native app, it opens Google's own sign-in sheet directly, no redirect. g.auth.currentUser() answers the same way afterwards either way.
  • Founders too. You sign in to the Gemmein dashboard itself with the same Google button, on its own sign-in screen. If you've turned your authenticator app on, Gemmein still asks for your app code afterwards.
  • Your code. Web: g.auth.signInWithGoogle() redirects; call g.auth.completeGoogleRedirect() once on the page it returns to. Native, Expo, or a client that already holds a Google ID token: call g.auth.getGoogleNonce() first, pass its nonce into Google's own sign-in request, then g.auth.exchangeIdToken('google', idToken). See the SDK reference.
  • Google's own verification stands. A Google account whose email email_verified reads false is refused outright: never linked to an existing person, never used to create one.

What it does not do.

  • Ask for a password, or show Google's own consent screen again once a person is signed in.
  • Reach Live on its own. Development's switch, and a founder's own Google client, carry to Live only at go-live, that one time; after that Live's switch moves separately, and a promote never touches it.

When you need something else.

Example. A "Continue with Google" button beside the emailed code's own field.

// Web
await g.auth.signInWithGoogle()
// … back on the returnUrl page:
const session = await g.auth.completeGoogleRedirect()

// Native / Expo, with Google's own sign-in SDK
const nonce = await g.auth.getGoogleNonce()
// … pass nonce into Google's sign-in request, read its idToken back …
const session = await g.auth.exchangeIdToken("google", idToken)

What happens if…

If…What happensWhat you do
The switch is off for this app and environment503 google_signin_offTurn it on from Settings → Connections
The web redirect's returnUrl isn't one of your verified domains400 return_url_not_allowed, checked before anything startsPass a verified address
A captured callback link is opened in a different browser than the one that started it400 google_login_code_mismatch, logged, never a sessionStart sign-in again, in the same browser
The web redirect's login code is used twice, or its 2-minute window passes410 google_login_code_expiredGo back and start sign-in again
Google's ID token is forged, expired, malformed, for a different audience, carries no nonce at all, or email_verified is false400 invalid_id_token, never linked to an existing person or used to create oneStart sign-in again
The native exchange's nonce wasn't made by getGoogleNonce() for this app, or was already used400 google_nonce_requiredCall getGoogleNonce() first, and pass its nonce into Google's own sign-in request before reading its ID token
Too many attempts on the start, nonce, token or exchange call, from one app and address429 rate_limit_exceededWait for resetAt, then try again
You sign in to the dashboard with Google while the authenticator app is onGoogle alone doesn't sign you in; Gemmein still asks for your app code, the same as it would after an emailed codeEnter the app code
Was this page helpful?

Last updated