Vercel部署的Next.js项目Supabase Google OAuth登录异常排查
Next.js + Supabase 部署后Google OAuth重定向到localhost问题解决
问题描述
基于Next.js与Supabase开发的项目,本地开发阶段使用本地Supabase实例,Google OAuth登录功能正常。部署到Vercel后,已配置远程Supabase环境变量,在Google Console新建项目并设置匹配远程Supabase回调地址的重定向URL,同时在Vercel中配置了Client ID与Secret。但部署后的网站点击Google登录并选择账号后,页面被重定向至http://localhost:3000/?code=40e25cab-f6b2-466a-8f61-7ac27128ccbe,查看网络请求发现Supabase回调接口返回的Location头指向localhost。
相关请求信息
网络请求通用信息
Request URL: https://mumlxsmdqylggqktbgvb.supabase.co/auth/v1/callback?state=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTQ5NzkyNjUsInNpdGVfdXJsIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwIiwiaWQiOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAiLCJmdW5jdGlvbl9ob29rcyI6bnVsbCwicHJvdmlkZXIiOiJnb29nbGUiLCJyZWZlcnJlciI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCIsImZsb3dfc3RhdGVfaWQiOiI2YmI3YjgxMC0xNmJkLTRhY2EtODliNy03MmFhYjQ1NDE0Y2YifQ.ERh_o2IwWhYzKcqPGxiM4K3rKHexN1IhUJ_WzLqe-iE&code=4%2F0AdLIrYedV-WyTJXW99bndYHlxnw9tBpHnOs8SNWwQbdKs00TW6YoFAYT9xBta9n6I8vAGw&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&prompt=consent Request Method: GET Status Code: 302 Found Remote Address: 172.64.149.149:443 Referrer Policy: origin
响应头
Location: http://localhost:3000?code=0e068715-35e2-4b92-9a4a-43906ba97042
相关代码
登录按钮代码
'use client'; import { createSupabaseBrowserClient } from '@/lib/supabase/browser-clients'; import { Button } from '@/components/ui/button'; export default function LoginWithGoogleButton(props: { nextUrl?: string }) { const supabase = createSupabaseBrowserClient(); const handleLogin = async () => { await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: `${location.origin}/api/auth/callback?next=${ props.nextUrl || '' }`, queryParams: { access_type: 'offline', prompt: 'consent', }, }, }); }; return ( <Button size='sm' onClick={handleLogin}> Login with Google </Button> ); }
api/auth/callback/route.ts代码
import { NextResponse } from 'next/server'; import { createSupabaseServerClient } from '@/lib/supabase/server-clients'; export async function GET(request: Request) { const { searchParams, origin } = new URL(request.url); const code = searchParams.get('code'); // if "next" is in param, use it in the redirect URL // const next = searchParams.get('next') ?? '/'; if (code) { const supabase = createSupabaseServerClient(); const { error } = await supabase.auth.exchangeCodeForSession(code); if (!error) { return NextResponse.redirect(origin); } } // TODO: // return the user to an error page with instructions return NextResponse.redirect(`${origin}/auth/auth-error`); }
解决方案
1. 修正Supabase项目的站点URL配置
- 登录Supabase控制台,进入目标项目的Authentication > URL Configuration页面
- 将Site URL设置为Vercel部署后的生产域名(如
https://your-project.vercel.app),替换原有的localhost地址 - 在Redirect URLs中添加生产环境的回调地址:
https://your-project.vercel.app/api/auth/callback
2. 替换redirectTo的动态获取方式
客户端代码中location.origin在静态部署场景下可能存在取值异常,改为从环境变量读取生产域名:
'use client'; import { createSupabaseBrowserClient } from '@/lib/supabase/browser-clients'; import { Button } from '@/components/ui/button'; export default function LoginWithGoogleButton(props: { nextUrl?: string }) { const supabase = createSupabaseBrowserClient(); const handleLogin = async () => { // 从环境变量获取生产域名,避免location.origin的不确定性 const redirectUrl = `${process.env.NEXT_PUBLIC_APP_URL}/api/auth/callback?next=${props.nextUrl || ''}`; await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: redirectUrl, queryParams: { access_type: 'offline', prompt: 'consent', }, }, }); }; return ( <Button size='sm' onClick={handleLogin}> Login with Google </Button> ); }
- 在Vercel的环境变量设置中添加
NEXT_PUBLIC_APP_URL,值为你的生产域名(如https://your-project.vercel.app)
3. 验证Supabase客户端初始化配置
检查createSupabaseBrowserClient和createSupabaseServerClient的代码,确保使用远程Supabase项目的环境变量,而非本地实例:
// 示例:browser-clients.ts import { createBrowserClient } from '@supabase/ssr'; export function createSupabaseBrowserClient() { return createBrowserClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! ); }
- 确认Vercel中配置的
NEXT_PUBLIC_SUPABASE_URL和NEXT_PUBLIC_SUPABASE_ANON_KEY是远程Supabase项目的对应值,不是本地的http://localhost:54321
4. 清除缓存并重新部署
- 在Vercel后台触发重新部署,勾选"Redeploy with cache cleared"选项,避免旧环境变量缓存导致的问题
- 测试时使用浏览器无痕模式,或清除现有缓存,确保加载的是最新部署的代码
内容的提问来源于stack exchange,提问作者Noor Fatima
相关产品推荐
相关产品推荐

