Python — FastAPI Development
Google and Apple Sign-In in Expo, Verified by FastAPI
Direct answer
When a user signs in with Google or Apple in Expo, your app receives an OIDC identity token from the provider — do not send that token to your protected API as if it were your own. Send it once to a FastAPI endpoint that verifies the signature against Google's or Apple's public keys, checks the audience and issuer, then mints your own access and refresh tokens for that user. From then on the app uses your JWTs exactly like a password login, and the provider is out of the request path.
Federated login looks like it removes work, and it does — until you treat the provider's token as your session token and wire your whole API around Google. The clean pattern is a one-time exchange: verify their token, create or find the user, hand back your own tokens. Your API never learns the word Google again.
Key facts, with sources
- In the JetBrains Python Developers Survey 2024, which collected responses from more than 30,000 Python developers, FastAPI usage jumped from 29% to 38%, overtaking Django (35%) and Flask (34%) as the most-used Python web framework. (JetBrains Python Developers Survey 2024)
- The 2025 Stack Overflow Developer Survey shows FastAPI at 14.8% of respondents doing extensive work with it, edging out Flask at 14.4% and Django at 12.6%. (Stack Overflow Developer Survey 2025)
- FastAPI's official documentation cites independent TechEmpower benchmarks showing FastAPI applications running under Uvicorn as one of the fastest Python frameworks available, ranked only below Starlette and Uvicorn themselves. (FastAPI official documentation)
- FastAPI surpassed Flask in GitHub stars in December 2025, reaching roughly 88,000 stars compared to Flask's 68,400. (DZone)
- Industry analysis of FastAPI's 2025 growth reports about 40% year-over-year growth in job mentions and production adoption at companies including Uber, Netflix, and Microsoft. (byteiota)
The flow: verify once, then use your own tokens
The client runs the provider's sign-in and gets back an ID token — a signed JWT from Google or Apple. It sends that token to a single endpoint on your backend. The backend verifies it, maps it to a user in your database, and issues your own access and refresh tokens. Every request after that carries your JWT, validated by your rotation and reuse-detection logic. The provider participated in exactly one request.
The reason not to skip the exchange: if your API trusts Google's token directly, you inherit Google's expiry, Google's audience rules, and no ability to revoke or rotate on your terms. Minting your own session decouples your app from the identity provider entirely.
Verify the Google ID token in FastAPI
Google publishes its public keys; the google-auth library fetches and caches them and checks the signature, expiry, and audience in one call. Confirm the issuer too, then create or fetch the user and return your own tokens.
from google.oauth2 import id_token
from google.auth.transport import requests as google_requests
GOOGLE_CLIENT_ID = "your-client-id.apps.googleusercontent.com"
@router.post("/auth/google")
def google_sign_in(body: GoogleIn, db: Session = Depends(get_db)):
try:
# Verifies signature, expiry, and audience against Google's public keys.
claims = id_token.verify_oauth2_token(
body.id_token, google_requests.Request(), GOOGLE_CLIENT_ID
)
except ValueError:
raise HTTPException(401, "invalid Google token")
if claims["iss"] not in ("accounts.google.com", "https://accounts.google.com"):
raise HTTPException(401, "wrong issuer")
user = get_or_create_user(db, email=claims["email"], name=claims.get("name"))
# From here the app uses YOUR tokens; Google is out of the request path.
return {
"access_token": mint_access_token(user.id),
"refresh_token": issue_refresh_token(db, user.id),
}Apple's extra rules
Apple sign-in follows the same verify-then-exchange shape but has two quirks that bite teams. First, Apple only sends the user's name on the very first authorization — if you do not capture it then, you never get it again, so persist it on first sign-in. Second, many users choose Apple's private relay email (a masked address); treat that as the stable identifier and do not assume you can email it through arbitrary providers. Verify Apple's identity token against Apple's public keys the same way, checking the issuer is https://appleid.apple.com and the audience is your app's bundle or service ID.
One user, multiple sign-in methods
Match federated logins to existing accounts by verified email so a user who signed up with a password and later taps Sign in with Google lands on the same account, not a duplicate. Store which providers are linked. The exchange endpoint stays the entry point for every provider — each one verifies its own token, then converges on the same get_or_create_user and the same token issuance.
When to hire senior help
Bring in senior help when your API needs to handle real concurrency, when you are designing service boundaries and auth for the first time, or when an existing FastAPI codebase mixes sync and async code and latency is degrading. An experienced engineer can usually diagnose event-loop blocking and connection-pool misconfiguration in days, which is far cheaper than re-architecting after launch. If your stack includes React Native + Python + AI, a senior engineer who owns the full product beats coordinating multiple juniors.
Bottom line
Dhairya Senjaliya ships Python — FastAPI Development projects worldwide — book a scoping call to discuss your specific situation.
Common pitfalls to avoid
- ✕Calling blocking libraries (classic SQLAlchemy sessions, requests, heavy file I/O) inside async def endpoints, which stalls the event loop and erases FastAPI's concurrency advantage
- ✕Deploying a single Uvicorn process with no process manager or worker scaling, leaving most CPU cores idle under production load
- ✕Treating the auto-generated OpenAPI docs as a versioning strategy, then breaking mobile and partner clients when response schemas change
- ✕Running large payloads through deeply nested Pydantic models on every request and response, adding serialization latency that shows up only at scale
Frequently asked questions
Can I just send Google's token to my API on every request?
You can, but you shouldn't. It ties your API's session lifetime and validation to Google, removes your ability to rotate or revoke on your own terms, and couples every endpoint to a third party. Exchange it once for your own JWTs and keep the provider out of the hot path.
How do I verify the token without calling Google on every login?
The google-auth library caches Google's public keys and verifies the token's signature locally, so you are not making a network round-trip to Google per login after the keys are cached. Apple works the same way against its published keys.
Why does Apple only give me the user's name once?
Apple returns the full name only on the first authorization for privacy reasons. Persist it to your database on that first sign-in; on later logins the token carries the stable user identifier but not the name.
Is FastAPI mature enough for production?
Yes. It was the most-used Python web framework in the JetBrains 2024 survey at 38%, and companies including Uber, Netflix, and Microsoft run it in production. The ecosystem for auth, ORMs, and testing is now well established.
How much faster is FastAPI than Flask or Django really?
Independent TechEmpower benchmarks place FastAPI among the fastest Python frameworks, and published comparisons show several times Flask's throughput on I/O-bound endpoints. For CPU-bound work or database-bottlenecked apps, the framework choice matters far less than query and infrastructure design.
Should we pick FastAPI or Django for a new SaaS backend?
FastAPI suits API-first products, microservices, and ML model serving because of async support and automatic OpenAPI docs. Django ships batteries included (admin, ORM, auth) and is often faster to launch a conventional CRUD product. Many teams run both, per the JetBrains finding that a third of Django developers also use Flask or FastAPI.
Bottom line: Dhairya Senjaliya ships Python — FastAPI Development projects worldwide. Book a scoping call at https://dhairyasenjaliya.com/#book-call.