· Research AI
Google OAuth for Research AI: How the Sign-In Loop Actually Works
UI는 한국어입니다. 글 본문은 아직 영어 또는 중국어만 있습니다.
Research AI lets guests use cached learning topics for free. Gmail sign-in unlocks unlimited live AI research.
That sounds simple in the UI: click Sign in with Google. Under the hood, four systems must agree on the same OAuth contract:
- Google Cloud owns the OAuth client.
- Vercel owns production environment variables.
- Auth.js / NextAuth owns the callback route.
- Research AI owns the product rule: signed-in users bypass the demo live-run limit.
If any one of those is wrong, the user sees a generic sign-in failure.
The Mental Model
OAuth is a redirect handshake, not a password exchange.
User
-> Research AI /login
-> Auth.js creates a Google authorization URL
-> Google asks the user to approve
-> Google redirects back to Research AI callback URL
-> Auth.js exchanges the code using GOOGLE_CLIENT_SECRET
-> Research AI creates a session
The most important line is the callback:
https://research.xingai.app/api/auth/callback/google
That exact URI must exist in Google Cloud under Authorized redirect URIs. It must match protocol, domain, path, and trailing slash behavior exactly.
What Each Secret Does
GOOGLE_CLIENT_ID identifies the OAuth application. It is not very sensitive, but it must match the OAuth client configured in Google Cloud.
GOOGLE_CLIENT_SECRET proves that the server exchanging the authorization code is allowed to use that client. This is sensitive and belongs only in server-side environments such as Vercel Production variables or local .env.local.
AUTH_SECRET signs Auth.js cookies and session tokens.
AUTH_URL and NEXTAUTH_URL tell Auth.js the canonical production origin. For Research AI:
AUTH_URL=https://research.xingai.app
NEXTAUTH_URL=https://research.xingai.app
Google Cloud Setup
Open:
https://console.cloud.google.com/apis/credentials
Then:
- Select the Google Cloud project that owns the OAuth client.
- Open Credentials.
- Under OAuth 2.0 Client IDs, open the web client used by Research AI.
- Confirm the application type is Web application.
- Add this Authorized JavaScript origin:
https://research.xingai.app
- Add this Authorized redirect URI:
https://research.xingai.app/api/auth/callback/google
- Save and wait a short moment for Google to propagate the change.
For local dev, add the localhost callback too:
http://localhost:3000/api/auth/callback/google
Vercel Setup
In Vercel, add these variables to Production:
AUTH_SECRET=<32+ character random string>
AUTH_URL=https://research.xingai.app
NEXTAUTH_URL=https://research.xingai.app
GOOGLE_CLIENT_ID=<Google OAuth web client id>
GOOGLE_CLIENT_SECRET=<Google OAuth web client secret>
After changing Vercel env vars, redeploy. Existing deployments do not automatically pick up new environment variables.
cd /Users/xing/Desktop/ai-projects-work-space/xingai-research-ai
vercel deploy --prod --yes --force
The deployment should finish with:
readyState: READY
Aliased: https://research.xingai.app
Research AI Implementation
Research AI uses Auth.js / NextAuth.
Key files:
auth.ts
lib/oauth-credentials.ts
lib/auth-config.ts
app/api/auth/[...nextauth]/route.ts
app/actions/auth.ts
app/login/page.tsx
The OAuth client is loaded from:
GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET
AUTH_GOOGLE_ID
AUTH_GOOGLE_SECRET
AUTH_GOOGLE_CLIENT_ID
AUTH_GOOGLE_CLIENT_SECRET
Only one valid id/secret pair is needed. Do not mix a client id from one Google Cloud OAuth client with a secret from another.
How Research AI Uses the Session
The product rule is not “login wall first.” The rule is:
Cached topics are free.
Anonymous users get limited live AI runs.
Signed-in Gmail / @xingai.app users bypass the live-run limit.
The frontend resolves the session on the server and passes a verified identity to the API; the API must not trust identity it cannot verify. Cached topic reads stay free either way.
Common Failure Modes
1. Login page says to add GOOGLE_CLIENT_ID / SECRET
Auth is not configured in the active deployment.
Check:
vercel env ls
Then redeploy:
vercel deploy --prod --yes --force
2. Login page shows “Sign-in failed”
The app has some auth configuration, but Google rejected the OAuth handshake.
Most common causes:
- Missing Authorized redirect URI in Google Cloud.
- Redirect URI has
httpinstead ofhttps. - Redirect URI uses localhost in production.
- Client id and client secret are from different OAuth clients.
- Vercel env was changed but production was not redeployed.
- The active domain alias still points to an older deployment.
3. MissingCSRF when testing with curl
That is expected if you directly POST to the Auth.js sign-in endpoint without first fetching the CSRF token and cookie.
Browser clicks handle this automatically.
4. Vercel deployment is ready, but the domain still shows old UI
Inspect the deployment:
vercel inspect <deployment-url>
Confirm aliases include:
https://research.xingai.app
If not, alias it:
vercel alias set <deployment-url> research.xingai.app
Smoke Test
After redeploy:
curl -I https://research.xingai.app/login
Expected:
HTTP/2 200
x-matched-path: /login
Then test in the browser:
- Open
https://research.xingai.app/login. - Click Sign in with Google.
- Google should show the account chooser.
- After approval, Research AI should redirect back to
/.
The Lesson
OAuth failures often look like UI bugs, but they are usually contract mismatches.
For Research AI, the contract is:
Google Cloud redirect URI
== Auth.js callback route
== Vercel production domain
== active deployment alias
Once those four pieces match, Google sign-in becomes boring. That is the goal.