Next.js + @supabase/ssr中Github OAuth登录后无法获取会话数据
问题诊断与解决方案
针对Next.js + Supabase SSR场景下,OAuth登录后Cookie存在但Middleware无法获取会话的问题,可按以下步骤排查解决:
1. 检查Middleware中Supabase客户端初始化逻辑
确保使用createServerClient时正确处理Cookie传递,且Cookie配置与前端/控制台一致:
import { createServerClient } from '@supabase/ssr' import { NextResponse, type NextRequest } from 'next/server' export async function middleware(request: NextRequest) { let response = NextResponse.next({ request: { headers: request.headers } }) const supabase = createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { get(name: string) { return request.cookies.get(name)?.value }, set(name: string, value: string, options: any) { request.cookies.set({ name, value, ...options }) response.cookies.set({ name, value, ...options }) }, remove(name: string, options: any) { request.cookies.set({ name, value: '', ...options }) response.cookies.set({ name, value: '', ...options }) }, }, } ) const { data: { session }, error } = await supabase.auth.getSession() // 调试用:打印会话与错误信息 console.log('Session:', session, 'Error:', error) // 保护路由逻辑 if (!session && request.nextUrl.pathname.startsWith('/dashboard')) { return NextResponse.redirect(new URL('/login', request.url)) } return response }
- 本地开发时,确保Cookie的
secure选项设为false(生产环境需设为true),否则服务端无法读取Cookie。
2. 验证OAuth回调路由的会话持久化
检查auth/callback/route.ts是否正确完成代码兑换并更新Cookie:
import { createServerClient } from '@supabase/ssr' import { cookies } from 'next/headers' import { NextResponse } from 'next/server' export async function GET(request: Request) { const { searchParams } = new URL(request.url) const code = searchParams.get('code') if (code) { const cookieStore = cookies() const supabase = createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { get: (name) => cookieStore.get(name)?.value, set: (name, value, options) => cookieStore.set({ name, value, ...options }), remove: (name, options) => cookieStore.set({ name, value: '', ...options }), }, } ) // 兑换授权码为会话,自动更新Cookie const { error } = await supabase.auth.exchangeCodeForSession(code) if (error) console.error('Callback error:', error) } return NextResponse.redirect(new URL('/', request.url)) }
- 回调完成后需确保重定向的请求携带更新后的Cookie,可通过浏览器开发者工具的Network面板验证。
3. 核对Supabase控制台与Cookie配置
- 确认Supabase控制台Auth设置中的Site URL与应用域名完全一致(本地开发为
http://localhost:3000)。 - 检查Cookie的
path是否为/,确保所有路由都能访问到认证Cookie;跨域场景需配置正确的domain参数。
4. 调整Middleware匹配规则
确保matcher覆盖受保护路由,同时排除OAuth回调路由避免循环重定向:
export const config = { matcher: [ '/((?!api|_next/static|_next/image|favicon.ico|auth/callback).*)', // 或针对特定保护路由:'/dashboard/:path*' ], }
5. 调试会话获取细节
- 在Middleware中打印
request.cookies,确认sb-access-token、sb-refresh-token等Cookie是否存在且有效。 - 查看
supabase.auth.getSession()的error字段,根据错误信息定位问题(如JWT签名无效、Cookie过期等)。
内容的提问来源于stack exchange,提问作者theProgrammer
相关产品推荐
相关产品推荐

