Next.js 13中Supabase社交登录重定向失效问题求助
NextJS 13 + Supabase 认证重定向问题解决方案
问题分析
你遇到的核心问题是:OAuth登录回调完成后,用户已成功建立会话,但中间件未及时检测到会话,且登录页未自动跳转到原受保护页面。主要原因包括:中间件缺少必要的客户端初始化逻辑、登录页未监听会话状态变化、OAuth回调后的重定向逻辑不完善。
解决方案
1. 修复中间件代码
确保正确导入Supabase中间件客户端,并完善会话检测与重定向逻辑:
import { NextResponse } from "next/server"; import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs/middleware' export async function middleware(req) { const res = NextResponse.next(); const supabase = createMiddlewareClient({ req, res }); const { data: session } = await supabase.auth.getSession(); // 用户已登录,直接放行请求 if (session?.session) { return res; } // 未登录则重定向到登录页,携带完整的原页面路径(含查询参数) const redirectUrl = req.nextUrl.clone(); redirectUrl.pathname = "/login"; redirectUrl.searchParams.set('redirectedFrom', req.nextUrl.href); return NextResponse.redirect(redirectUrl); } export const config = { matcher: [ '/protected-page', // 受保护页面路径 // 可添加更多路径,例如 '/dashboard/:path*' '!/login', // 排除登录页,避免拦截OAuth回调请求 ], };
2. 完善登录页的会话监听与重定向逻辑
在登录页中添加会话状态监听,登录成功后自动跳转到目标页面:
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs"; import { Auth } from "@supabase/auth-ui-react"; import { ThemeSupa } from "@supabase/auth-ui-shared"; import { useSearchParams, useRouter } from "next/navigation"; import { useEffect, useState } from "react"; export default function Login() { const searchParams = useSearchParams(); const redirectedFrom = searchParams.get("redirectedFrom") || "/"; const router = useRouter(); const supabase = createClientComponentClient(); const [session, setSession] = useState(null); // 监听会话状态变化 useEffect(() => { // 初始化获取当前会话 const fetchSession = async () => { const { data: { session } } = await supabase.auth.getSession(); setSession(session); }; fetchSession(); // 订阅会话更新事件 const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, newSession) => { setSession(newSession); }); return () => subscription.unsubscribe(); }, [supabase]); // 会话建立后立即重定向到目标页面 useEffect(() => { if (session) { router.push(redirectedFrom); } }, [session, redirectedFrom, router]); // 构建OAuth回调URL(需与Supabase控制台配置一致) const redirectURL = () => { let url = process?.env?.NEXT_PUBLIC_OAUTH_REDIRECT_URL ?? process?.env?.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000"; url = url.includes("http") ? url : `https://${url}`; return `${url}/login`; }; return ( <div className="container mx-auto p-6"> <div className="flex items-start justify-center"> <div className="w-96 rounded-lg p-6 shadow-lg md:mt-10"> <Auth supabaseClient={supabase} appearance={{ theme: ThemeSupa }} providers={["google"]} redirectTo={redirectURL()} /> </div> </div> </div> ); }
3. 检查Supabase控制台配置
在Supabase控制台的Authentication -> URL Configuration中确认:
Site URL设置为你的项目域名(本地开发为http://localhost:3000)Redirect URLs包含登录页完整路径(例如http://localhost:3000/login)
内容的提问来源于stack exchange,提问作者adeelmahmood
相关产品推荐
相关产品推荐

