[實作筆記] 個人自動化平台(番外) Google OAuth redirect_uri_mismatch 除錯記錄

前情提要

個人自動化平台(六) 實作 IG Token 工具時,

為了修 Instagram OAuth callback URL 的問題,在 Vercel 設了 NEXT_PUBLIC_BASE_URL

沒想到這個動作讓 Google 登入炸掉,報 redirect_uri_mismatch

表面上是「連帶損傷」,但根本原因是 production 的 Google 登入從來沒測試過,問題早就存在,只是這次才被發現。


事件時間線

背景:production Google 登入從來沒運作過

NEXT_PUBLIC_BASE_URL 在 Vercel 上沒有設值時,env.baseUrlundefined,Google OAuth 送出的 redirect URI 是:

1
undefined/api/auth/google/callback

這個字串不可能通過 Google 驗證。

但 production 上從來沒有人測試過 Google 登入,所以一直沒被發現。

本機開發設的是 NEXT_PUBLIC_BASE_URL=http://localhost:3000,Google Console 也只登記了 http://localhost:3000/api/auth/google/callback,本機正常,所以沒有警覺。

起點:IG Token 工具的 Instagram OAuth callback URL 錯誤

實作 IG Token 工具時(demo.marsen.me),Instagram 授權完成後 callback 沒有導回正確的頁面,而是跑到 Vercel 內部 URL。

原因:Instagram callback route 的 baseUrl 在 Vercel 上沒有設定,fallback 讀到的是 Vercel 執行環境的 host,不是對外的 demo.marsen.me

修法:在 Vercel 設定 NEXT_PUBLIC_BASE_URL

在 Vercel 環境變數加上:

1
NEXT_PUBLIC_BASE_URL=https://demo.marsen.me

因為專案用 vercel build --prebuilt 方案,直接 Redeploy 不會重新 build,必須 push 新的空 commit 觸發 GitHub Actions:

1
2
git commit --allow-empty -m "chore: trigger redeploy"
git push origin main

Instagram OAuth callback 正常了。

問題浮現:第一次在 production 測試 Google 登入

設了 NEXT_PUBLIC_BASE_URL 後,第一次真正在 production 試 Google 登入。

NEXT_PUBLIC_BASE_URL 同時影響 Google OAuth 的 redirect URI(src/app/api/auth/google/route.ts):

1
2
3
4
5
const google = new Google(
env.googleClientId,
env.googleClientSecret,
`${env.baseUrl}/api/auth/google/callback`,
)

app 送出的 redirect_uri 變成:

1
https://demo.marsen.me/api/auth/google/callback

但 Google Cloud Console 只登記了本機的那條:

1
http://localhost:3000/api/auth/google/callback

不符,報 redirect_uri_mismatch


症狀

點「Google 登入」後,Google 跳出錯誤頁面:

1
2
已封鎖存取權:這個應用程式的要求無效
發生錯誤 400:redirect_uri_mismatch

解法

進 Google Cloud Console → Credentials → OAuth 2.0 Client → Authorized redirect URIs,新增:

1
https://demo.marsen.me/api/auth/google/callback

本機那條 http://localhost:3000/api/auth/google/callback 保留,本機開發還用得到。

存檔幾分鐘內生效,不需要重新 build 或 deploy。


參考

小結

  • 根本原因不是「設定改壞了」,而是 production Google 登入從來沒被測試過,問題一直存在
  • IG Token 工具需要在 Vercel 設 NEXT_PUBLIC_BASE_URL,這個動作讓潛藏的問題第一次浮現
  • redirect_uri_mismatch 代表 app 送出的 redirect URI 和 Google Console 登記的不符
  • NEXT_PUBLIC_BASE_URL 影響所有 OAuth 服務,改了就要同步更新各 Console 的 redirect URI
  • Google Console 可以同時登記多條 URI,本機和 production 各一條,互不影響
  • vercel build --prebuilt 的專案,env var 更新後要 push 空 commit 才會生效

(fin)

Please enable JavaScript to view the Gitalk. :D
Please enable JavaScript to view the LikeCoin. :P
Please enable JavaScript to view the LikeCoin. :P