Next.js中用Supabase和SSR实现OAuth遇问题求助
Next.js + Supabase SSR OAuth认证流程中断问题解决
我在Next.js项目中使用Supabase结合@supabase/ssr集成OAuth认证,MagicLink和邮箱认证功能正常,但Google等社交提供商登录时流程意外中断。
现有实现代码
邮箱登录函数
async function signInWithEmail(formData: FormData) { "use server" const origin = headers().get("origin") const email = formData.get("email") as string const cookieStore = cookies() const supabase = createClient(cookieStore) const { error } = await supabase.auth.signInWithOtp({ email: email, options: { emailRedirectTo: `${origin}/auth/callback`, }, }) if (error) { console.error(error) return redirect("/login?message=Could not authenticate user") } redirect("/login?message=Check your email inbox to continue signing in") }
认证回调代码
import { createClient } from "@/lib/supabase/server" import { NextResponse } from "next/server" import { cookies } from "next/headers" export async function GET(request: Request) { const requestUrl = new URL(request.url) const code = requestUrl.searchParams.get("code") if (code) { const cookieStore = cookies() const supabase = createClient(cookieStore) await supabase.auth.exchangeCodeForSession(code) } return NextResponse.redirect(requestUrl.origin) }
Supabase客户端初始化代码(lib/supabase/server.ts)
import { createServerClient, type CookieOptions } from "@supabase/ssr" import { cookies } from "next/headers" export const createClient = (cookieStore: ReturnType<typeof cookies>) => { return createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { get(name: string) { return cookieStore.get(name)?.value }, set(name: string, value: string, options: CookieOptions) { try { cookieStore.set({ name, value, ...options }) } catch (error) { console.error(error) } }, remove(name: string, options: CookieOptions) { try { cookieStore.set({ name, value: "", ...options }) } catch (error) { console.error(error) } }, }, } ) }
存在问题的OAuth登录函数
async function signInWithSocialProvider(provider: any) { "use server" const origin = headers().get("origin") const cookieStore = cookies() const supabase = createClient(cookieStore) const { error } = await supabase.auth.signInWithOAuth({ provider: provider, options: { redirectTo: `${origin}/auth/callback`, }, }) if (error) { console.error(error) return redirect("/login?message=Could not authenticate user") } }
问题详情
- 核心疑问:
- Supabase与SSR的OAuth配置中是否存在遗漏?
- 该问题是否由Supabase或Next.js配置错误导致?
- 预期行为:选择Google等社交提供商后,跳转至提供商登录页,完成认证后返回应用并建立会话。
- 实际行为:OAuth初始请求后流程停滞,能生成
sb-xxx-auth-token-code-verifiercookie,但未跳转至Google登录页,认证未完成。 - 相关日志:生成了名为
sb-mlirbfytwbmtpcchmvlr-auth-token-code-verifier的cookie,值为d8d738ef35947d057b013bb19adaee03e44d74003c47ea27b8426b59df264ece2a9f98f78fbdfc5d3e562f021bdf0e0460b633246e889b6c
解决方案
问题出在OAuth登录函数中未处理signInWithOAuth返回的跳转URL。修改后的完整函数如下:
async function signInWithSocialProvider(provider: any) { "use server" const origin = headers().get("origin") const cookieStore = cookies() const supabase = createClient(cookieStore) const { data, error } = await supabase.auth.signInWithOAuth({ provider: provider, options: { redirectTo: `${origin}/auth/callback`, }, }) if (error) { console.error(error) return redirect("/login?message=Could not authenticate user") } redirect(data.url) }
关键修改点
- 从
supabase.auth.signInWithOAuth的返回值中解构出data对象 - 在函数末尾添加
redirect(data.url),触发跳转到社交提供商的登录页面
内容的提问来源于stack exchange,提问作者Mathias Riis Sorensen
相关产品推荐
相关产品推荐

