I Wasted 3 Days on Google Drive 'Open With' OAuth — Here's Everything I Learned

2026-11-12来源 dev.toEnglish

Three days. That's how long it took me to fix a single OAuth error that, in hindsight, had a five-minute solution. The catch? The fix was in a place I never thought to look.

If you're building a Google Drive "Open With" App and you're seeing:

Error 400: redirect_uri_mismatch 

...this post is for you. I'll walk through exactly how to diagnose it, why the usual advice doesn't work, and the specific steps that actually fixed it.

The Setup

I was building an AI powered document processing tool RenomeeAI that integrates with Google Drive. The idea: users right-click a file in Drive → "Open With" → my app → OAuth flow → process the file.

Here's the full flow:

┌──────────────┐ ┌─────────────────────┐ ┌──────────────┐ │ Google Drive │ │ drive-api.renomeeai │ │ Google APIs │ │ (client) │ │ (FastAPI) │ │ │ └──────┬───────┘ └──────────┬───────────┘ └──────┬───────┘ │ │ │ │ 1. Right-click → "Open │ │ │ With" — Drive builds │ │ │ OAuth URL │ │ │──────────────────────────►│ │ │ │ │ │ │ 2. Redirect → Google auth │ │◄───────────────────────────┼────────────────────────────│ │ User clicks Allow │ │ │ │ 3. callback: code → token │ │ │───────────────────────────►│ │ │◄───────────────────────────│ │ │ access_token+refresh_token│ │ │ │ │ │ 4. Encrypt → DB, set Cookie│ │◄───────────────────────────│ │ │ │ │ │ 5. Frontend: session/init │ │ │──────────────────────────►│ │ │ │ 6. Fetch file metadata │ │ │───────────────────────────►│ │ │◄───────────────────────────│ │◄───────────────────────────│ files: [name, mimeType, │ │ { needs_auth, files } │ imageMetadata] │ │ │ │ │ 7. User enters rename cmd │ │ │──────────────────────────►│ │ │ │ 8. Call RenameAI │ │ │──────► api.renameai.com │ │ │◄────── suggested_name │ │◄───────────────────────────│ │ │ { suggested_name } │ │ │ │ │ │ 9. User confirms → apply │ │ │──────────────────────────►│ │ │ │ 10. PATCH Drive filename │ │ │───────────────────────────►│ │◄───────────────────────────│◄───────────────────────────│ │ { success, new_name } │ │ 

During local development, I used ngrok to expose my local server. I registered my ngrok URL in Google Cloud Console as the OAuth redirect URI and everything worked fine.

When I moved to production, I:

  • Updated the Redirect URI in GCP Console to my real domain
  • Updated my server's .env file
  • Rebuilt and redeployed the Docker container

Then I tested the "Open With" flow and got:

Error 400: redirect_uri_mismatch The redirect URI in the request did not match a registered redirect URI. Request details: redirect_uri: https://7886-45-78-56-186.ngrok-free.app/drive/open 

That's my old ngrok URL. From months ago. It didn't make any sense.

Why Your .env Changes Have Zero Effect Here

This is the part that trips up almost everyone, including me.

There are two completely separate OAuth flows in a Drive integration:

Flow Who builds the OAuth URL Where redirect_uri comes from
Your /auth/start route Your server Your .env or config
Drive "Open With" native flow Google Drive's servers Drive UI Integration settings

The URL I saw in the Network tab — the one with my old ngrok address — was constructed by Google's servers, not mine. My code had nothing to do with it. My .env was irrelevant. No matter how many times I restarted my container, the URL would keep using whatever was stored in Google's backend registry for my app.

Once I understood this, everything else clicked.

Step 1: Get the Actual redirect_uri from Chrome DevTools

Before changing anything, get the ground truth.

  1. Open Google Drive, right-click a file → Open With → your app
  2. Before the error page appears, open DevTools (F12) → Network tab
  3. Filter for accounts.google.com
  4. Find the request, copy the full URL

The URL you're looking for looks like this:

https://accounts.google.com/o/oauth2/auth ?scope=https://www.googleapis.com/auth/drive.file &client_id=YOUR_CLIENT_ID.apps.googleusercontent.com &response_type=code &access_type=offline &redirect_uri=https://7886-45-78-56-186.ngrok-free.app/drive/open ← the problem &state=%7B%22ids%22%3A%5B%22xxx%22%5D%2C%22action%22%3A%22open%22%2C%22userId%22%3A%22xxx%22%7D 

Pay attention to the redirect_uri parameter. If it's an old ngrok address or any domain you no longer use — this URL was built by Google's servers, not yours.

  1. Extract it with:
python3 -c " import urllib.parse as u url = 'PASTE_FULL_URL_HERE' qs = u.parse_qs(u.urlparse(url).query) print('redirect_uri:', qs.get('redirect_uri', ['not found'])[0]) " 

If you see an old domain, a ngrok address, or anything that's not your current production URL — that's coming from Google's app registry, not your server. Keep reading.

Step 2: Query the App Registry Directly (The Only Source of Truth)

Google Cloud Console shows you what you submitted. The Drive API's apps.get endpoint shows you what Drive is actually using. These can diverge significantly, especially if your app was configured months ago.

Get an access token via OAuth Playground

  1. Go to developers.google.com/oauthplayground
  2. Click ⚙️ (top right) → optionally use your own credentials
  3. In Step 1, enter this scope and authorize:
 https://www.googleapis.com/auth/drive.apps.readonly 
  1. Complete the OAuth flow, then click Exchange authorization code for tokens
  2. Copy the Access token

Query your app's registry entry

TOKEN="paste_your_access_token" APP_ID="YOUR_PROJECT_NUMBER" # Your GCP project number (all digits), NOT project ID curl -s \ -H "Authorization: Bearer $TOKEN" \ "https://www.googleapis.com/drive/v3/apps/$APP_ID?fields=id,name,openUrlTemplate,installed,authorized" \ | python3 -m json.tool 

Note: APP_ID is your project number (all digits), not the project ID string. Get it with:

gcloud projects describe YOUR_PROJECT_ID --format="value(projectNumber)" 

This is where I found the smoking gun.

The openUrlTemplate field looked like this:

"openUrlTemplate": "https://accounts.google.com/o/oauth2/auth?scope=...&redirect_uri=https://7886-45-78-56-186.ngrok-free.app/drive/open&..." 

Google had literally hard-coded my old ngrok URL inside the OAuth template that Drive uses to build authorization requests. This template lives server-side at Google. Changing my GCP Console settings didn't update it.

Step 3: The Real Fix — Drive UI Integration Settings

Navigate to:

Google Cloud Console → APIs & Services → Enabled APIs & Services → Google Drive API → Drive UI Integration tab 

The root cause: "Automatically show OAuth 2.0 consent screen"

Look for this checkbox:

☐ Automatically show OAuth 2.0 consent screen when users open my application from Google Drive 

This was checked on my app. This is where the wrong redirect_uri came from in the first place.

When this option is enabled, Drive doesn't send users to your Open URL directly. Instead, it builds an OAuth wrapper URL — using the redirect_uri you had configured at the time you first enabled this option — and writes that wrapped URL into the Drive App Registry as your app's openUrlTemplate. That value doesn't update automatically when you later change your Redirect URI in GCP Console.

Google has deprecated this option — but plenty of older tutorials still recommend enabling it. Don't.

Step one: Uncheck it. Fix your Open URL. Save.

Open URL: https://your-production-domain.com/drive/open 

⚠️ Important: unchecking is necessary, but not sufficient.

These are two separate problems. The checkbox controls whether Drive continues to generate OAuth wrapper URLs. The Registry cache controls what URL Drive is currently using. Unchecking the box stops the bleeding — it doesn't automatically flush the old openUrlTemplate that's already stored in the Registry.

You must verify via apps.get that the Registry has actually updated. Don't trust the Console page.

Step 4: Verify the Registry Actually Updated

After saving, re-run the apps.get query from Step 2. Check every 10 minutes.

What you want to see:

"openUrlTemplate": "https://your-production-domain.com/drive/open?state={ids}&action={action}&userId={userId}" 

No more OAuth wrapper URL. No more old redirect URIs.

If it's still showing the old value after 1 hour, stop waiting and go straight to "When Nothing Works" below. The Registry for an old project may simply never sync. Waiting longer won't change that.

Step 5: Re-install the App After Config Changes

This one bit me a second time. Even after the registry showed the correct openUrlTemplate, my OAuth flow was still broken — because I had previously installed the app under my test account with the old configuration, and that installation was cached.

The correct re-install sequence:

  1. Disconnect the app: Google Drive → Settings → Manage apps → find your app → Disconnect
  2. Revoke OAuth permissions: myaccount.google.com/connections → find your app → Remove access
  3. Verify via apps.get: Run the API query again and confirm installed: false
  4. Wait until apps.get reflects the new config before re-authorizing
  5. Re-run the "Open With" flow to trigger a fresh install

If you skip step 4 and re-authorize before the registry updates, you'll re-install the old configuration and be back where you started.

Bonus: Adding New MIME Types (Images, PDFs, etc.)

I also needed to add image support to my app. I added the MIME types in Console, but after re-installing, images still didn't show up in the "Open With" menu.

The issue: existing app installations don't pick up new MIME type configurations. You have to fully uninstall and reinstall (following the sequence above).

Also, put file types under Secondary rather than Default:

Secondary MIME Types: application/pdf image/jpeg image/png image/webp Secondary File Extensions: pdf, jpg, jpeg, png, webp 

Setting types as "Default" makes your app the default opener, which is usually not what you want.

When Nothing Works: Create a New GCP Project

If you've done everything above and apps.get still returns the old openUrlTemplate after an hour, your project's app registry entry may be in a broken state. Google's backend caching for openUrlTemplate can sometimes get stuck.

Option A: Disable and re-enable the Drive API

gcloud services disable drive.googleapis.com --project=YOUR_PROJECT_ID gcloud services enable drive.googleapis.com --project=YOUR_PROJECT_ID 

Then re-save your Drive UI Integration settings. Sometimes this forces a registry refresh. Not guaranteed.

Option B: Create a new GCP project (recommended — and what actually fixed it for me)

After nearly a full day on the old project, I created a new one. The very first apps.get query returned the correct openUrlTemplate. The whole "Open With" flow worked on the first attempt. In hindsight, the time I spent waiting for the old project's Registry to sync was entirely wasted — a new project has no historical cache at all.

# Create the new project gcloud projects create my-app-drive-prod --name="My App Drive Prod" # Enable Drive API gcloud services enable drive.googleapis.com --project=my-app-drive-prod # Get the project number for apps.get queries gcloud projects describe my-app-drive-prod --format="value(projectNumber)" 

Configure the new project from scratch:

  1. OAuth consent screen → External → add your test users
  2. Credentials → Create OAuth Web Client → set the correct Redirect URI
  3. Drive UI Integration → leave "auto OAuth" unchecked → set Open URL and MIME types

Update your server's .env:

GOOGLE_DRIVE_CLIENT_ID=new_client_id GOOGLE_DRIVE_CLIENT_SECRET=new_client_secret 

Rebuild your container:

docker compose up -d --force-recreate app 

Diagnostic Flowchart

redirect_uri_mismatch error | v F12 → Network → copy OAuth URL → extract redirect_uri | v Is redirect_uri wrong (old ngrok, wrong domain)? | YES v OAuth Playground → get token → GET /drive/v3/apps/{appId} | v Does openUrlTemplate contain an OAuth wrapper URL? | YES v Drive API → Drive UI Integration tab → UNCHECK "Automatically show OAuth 2.0 consent screen" → Fix Open URL → Save | v Check apps.get every 10 min → is openUrlTemplate updated? | | NO (>1 hour) YES | | v v Create new GCP project Uninstall app → wait for apps.get to show installed:false → reinstall 

TL;DR

  1. Use F12 to get the real redirect_uri from the OAuth URL — don't guess
  2. Drive "Open With" OAuth URLs are built by Google's servers, not yours — .env changes don't affect them
  3. Uncheck "Automatically show OAuth 2.0 consent screen" — this is what wrote the wrong redirect_uri into the Registry in the first place
  4. Unchecking is necessary, not sufficient — the checkbox and the Registry cache are two separate problems
  5. GET /drive/v3/apps/{appId} is the only reliable way to verify what Drive is actually using; don't trust the Console page
  6. If the registry won't update after an hour, create a new GCP project — no historical cache, works immediately

If this saved you some time, the Google Drive API docs on UI Integration are worth a read — especially the deprecation notices on older features.

原文:https://www.a8q9.cn/en/article/i-wasted-3-days-on-google-drive-open-with-oauth-here-s-everything-i-learned-b7674c.html

相关文章