OAuth2
Google + GitHub sign-in.
OAuth2 means "sign in with Google / GitHub" â the user clicks a button, gets redirected to the provider, comes back authenticated. Grit ships handlers for both. This lesson covers the wiring; the provider setup is a one-time copy-paste.
The flow
User â Click "Sign in with Google"â GET /api/auth/googleâ Grit redirects to accounts.google.comâ Google authenticates userâ Google redirects to /api/auth/google/callback?code=...â Grit exchanges code for user infoâ Grit creates or finds the userâ Grit issues JWT (access + refresh tokens)â Frontend stores tokens, user is signed in
The 3-line provider setup
Get OAuth credentials from the provider once. For Google: create a project in Google Cloud Console, configure the consent screen, get client ID + secret. For GitHub: Developer Settings â OAuth Apps â New OAuth App.
Then add to .env:
# Google OAuthGOOGLE_CLIENT_ID=1234-...apps.googleusercontent.comGOOGLE_CLIENT_SECRET=GOCSPX-...# GitHub OAuthGITHUB_CLIENT_ID=Iv1....GITHUB_CLIENT_SECRET=...# Where to redirect after success (your web frontend)OAUTH_FRONTEND_URL=http://localhost:3001
That's it. Restart the API. Both providers are wired.
The callback URLs you give the provider
- Google:
http://localhost:8080/api/auth/google/callback - GitHub:
http://localhost:8080/api/auth/github/callback
For production, swap localhost:8080 for your real domain. Each provider lets you list multiple callback URLs â typically you'd list both your localhost dev URL and your production URL.
state token signed with JWT_SECRET. The callback verifies the state matches, preventing CSRF attacks during the OAuth handshake.Account linking â what happens if email already exists?
User signs up with alex@example.com + password. Later, they hit "Sign in with Google" and Google says "this account is alex@example.com". Grit's default: match the existing user, link the Google ID, sign them in. The user has both a password AND a Google login from then on.
If you want strict separation, edit authService.HandleOAuthCallback to reject the merge or prompt the user.
The user's profile data
What you get back from each provider:
Google: email, email_verified, name, picture, localeGitHub: email (sometimes private!), login (username), name, avatar_url
GitHub's "email" may be private. Grit's callback handler grabs the primary verified email from GET /user/emails if the primary endpoint hides it.
Quick check
Try it
Wire one OAuth provider (Google or GitHub â your pick) on your bench-api. Then trigger the flow:
- Open
http://localhost:8080/api/auth/googlein your browser - Sign in with your Google account
- You should land on the OAUTH_FRONTEND_URL with tokens in the query string
- Use that access token to hit
/api/auth/mewith curl
Paste the /me response in notes.md.
What's next
Password and OAuth handle the "something you know" factor. Next lesson â TOTP 2FA for the "something you have" factor.
Spot a typo? Have an idea?
Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled â suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.
Suggest an improvement on GitHub