Google OAuth Redirect URI Mismatch in Vercel Preview Deployments
Unanswered
Southern rough shrimp posted this in #help-forum
Southern rough shrimpOP
Standard OAuth Flow:
When a user tries to log in with Google, your Next.js app redirects them to Google's authentication page.
After successful authentication, Google redirects the user back to a specific URL in your app (the "redirect URI").
This redirect URI is configured in the Google Cloud Console.
Vercel Preview URLs:
Vercel creates unique, dynamic URLs for each pull request preview (e.g., https://your-project-git-branch-hash.vercel.app).
These URLs are different from your production URL (e.g., https://yourdomain.com).
The Mismatch:
Google OAuth requires the redirect URI to exactly match the URL configured in the Google Cloud Console.
When a user tries to log in from a Vercel preview, Google tries to redirect them to the preview URL.
However, the redirect URI in your Google Cloud Console is likely set to your production URL or localhost, causing a mismatch.
Google Cloud Console does not allow wildcards in the redirect URI, preventing a catch all.
The Result:
Google's OAuth server rejects the redirect, and the login fails.
When a user tries to log in with Google, your Next.js app redirects them to Google's authentication page.
After successful authentication, Google redirects the user back to a specific URL in your app (the "redirect URI").
This redirect URI is configured in the Google Cloud Console.
Vercel Preview URLs:
Vercel creates unique, dynamic URLs for each pull request preview (e.g., https://your-project-git-branch-hash.vercel.app).
These URLs are different from your production URL (e.g., https://yourdomain.com).
The Mismatch:
Google OAuth requires the redirect URI to exactly match the URL configured in the Google Cloud Console.
When a user tries to log in from a Vercel preview, Google tries to redirect them to the preview URL.
However, the redirect URI in your Google Cloud Console is likely set to your production URL or localhost, causing a mismatch.
Google Cloud Console does not allow wildcards in the redirect URI, preventing a catch all.
The Result:
Google's OAuth server rejects the redirect, and the login fails.
6 Replies
Cuvier’s Dwarf Caiman
I've been having the same problem!
I thought it was the configuration.
Gazami crab
any update on this? Google does not allow wild-cards in the oAuth client setup so cannot use preview URLs
Gazami crab
in client oAuth setup, inside Google Cloud, just add
https://vercel.app as Authorized JavaScript origins@Gazami crab in client oAuth setup, inside Google Cloud, just add `https://vercel.app` as Authorized JavaScript origins
Wirehaired Vizsla
Adding
Here are the two production ready ways to solve this for Vercel Preview Deployments:
### Method 1: Canonical Callback Proxy (Recommended)
Instead of having Google redirect directly to dynamic preview domains:
1. Always set your Google OAuth redirect URI to a fixed domain (e.g., your production domain
2. Before initiating the auth redirect from the preview URL, encode the current preview URL into the OAuth
```ts
// Encode state before redirecting to Google
const state = Buffer.from(JSON.stringify({ returnTo: window.location.origin })).toString('base64');
https://vercel.app to Authorized JavaScript origins won't fix the redirect mismatch because Google strictly enforces exact matching on Authorized redirect URIs (and prohibits wildcards).Here are the two production ready ways to solve this for Vercel Preview Deployments:
### Method 1: Canonical Callback Proxy (Recommended)
Instead of having Google redirect directly to dynamic preview domains:
1. Always set your Google OAuth redirect URI to a fixed domain (e.g., your production domain
https://yourapp.com/api/auth/callback/google or a dedicated auth proxy subdomain like https://auth.yourapp.com/...).2. Before initiating the auth redirect from the preview URL, encode the current preview URL into the OAuth
state parameter:```ts
// Encode state before redirecting to Google
const state = Buffer.from(JSON.stringify({ returnTo: window.location.origin })).toString('base64');
@Wirehaired Vizsla Adding `https://vercel.app` to Authorized JavaScript origins won't fix the redirect mismatch because Google strictly enforces exact matching on **Authorized redirect URIs** (and prohibits wildcards).
Here are the two production ready ways to solve this for Vercel Preview Deployments:
### Method 1: Canonical Callback Proxy (Recommended)
Instead of having Google redirect directly to dynamic preview domains:
1. Always set your Google OAuth redirect URI to a fixed domain (e.g., your production domain `https://yourapp.com/api/auth/callback/google` or a dedicated auth proxy subdomain like `https://auth.yourapp.com/...`).
2. Before initiating the auth redirect from the preview URL, encode the current preview URL into the OAuth `state` parameter:
ts
// Encode state before redirecting to Google
const state = Buffer.from(JSON.stringify({ returnTo: window.location.origin })).toString('base64');
Gazami crab
thanks. Your message suggested 2 methods, but I only see 1, maybe incomplete paste? Just thought I would double check