You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Supabase OAuth登录后重定向URL未附加code参数问题

Next.js + Supabase Google OAuth登录无code参数问题

问题描述

我正在用Next.js和Supabase实现Google社交登录,在用户通过Google认证后重定向到回调URL时出现异常:重定向URL的查询字符串里没有code参数,导致无法换代会话。

触发OAuth登录的代码如下:

const handleAuth = async (provider: 'google') => {
  try {
    setIsLoading(provider)
    const { error } = await supabase.auth.signInWithOAuth({
      provider,
      options: {
        redirectTo: 'http://localhost:3000/auth/callback',
      },
    })
    if (error) throw error
  } catch (error) {
    console.error('Error:', error)
  } finally {
    setIsLoading(null)
  }
}

我已经在Supabase设置里把授权重定向URI配置为http://localhost:3000/auth/callback。调试网络请求时观察到流程:

  1. 用户被重定向到Google登录页面;
  2. 登录后,Google重定向到Supabase端点,成功生成会话;
  3. Supabase将用户重定向回我的应用,但URL里没有预期的code参数。

我的配置

  • Google Cloud Console中的OAuth重定向URI:https://<supabase-project-id>.supabase.co/auth/v1/callback
  • Supabase重定向URI:http://localhost:3000/auth/callback
  • Supabase初始化代码:
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)

环境信息

•   Framework: Next.js 14.2.23
•   Supabase SDK: @supabase/supabase-js v2.26.0
•   OAuth Provider: Google
•   Environment: Localhost (http://localhost:3000)

预期结果

重定向URL应包含code参数,方便在回调处理程序中换代会话,示例:

http://localhost:3000/auth/callback?code=<authorization_code>

实际情况

重定向URL没有code参数,用户被重定向到:

http://localhost:3000/auth/callback

导致回调处理程序无法处理会话。

已尝试的解决方法

  • 验证Supabase中的重定向URI与Google Cloud Console配置一致;
  • 确认Supabase正确在服务商和我的应用之间转发请求;
  • 调试/auth/callback处理程序,确保正确提取查询参数;
  • 使用@supabase/auth-helpers-nextjs处理会话。

问题

  1. 为什么code参数没有包含在重定向URL中?
  2. 我是否遗漏了Supabase或Google的某项配置?
  3. 如何正确获取code参数以完成会话换取?

回调代码

// app/auth/callback/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'

export async function GET(request: Request) {
  const requestUrl = new URL(request.url)
  const code = requestUrl.searchParams.get('code')

  if (code) {
    const supabase = createRouteHandlerClient({ cookies })
    const { error } = await supabase.auth.exchangeCodeForSession(code)
    if (error) {
      console.error('Session exchange error:', error)
      return NextResponse.redirect(new URL('/auth/error', requestUrl.origin))
  } else {
    console.error('No authorization code found')
  }

  return NextResponse.redirect(new URL('/mypage', requestUrl.origin))
}

问题分析与解决方案

核心原因

  1. Supabase自动会话处理:Supabase在OAuth流程中,若检测到应用已初始化Supabase客户端,会直接在后台设置会话Cookie,无需通过URL传递code参数。此时手动提取code是多余的,Auth Helper会自动完成会话交换。
  2. Next.js路由缓存:Next.js 14的App Router默认可能缓存路由,导致回调页面无法正确获取查询参数。
  3. Supabase Site URL配置缺失:若未设置Site URL,Supabase无法正确设置跨域Cookie,可能影响会话传递逻辑。

具体解决步骤

1. 修正回调处理逻辑

使用@supabase/auth-helpers-nextjs时,无需手动提取code,直接传入完整的查询参数对象即可:

// app/auth/callback/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'

export const dynamic = 'force-dynamic' // 禁用路由缓存,确保每次请求都执行

export async function GET(request: Request) {
  const requestUrl = new URL(request.url)
  const supabase = createRouteHandlerClient({ cookies })

  // 直接传入searchParams,Auth Helper会自动处理code参数
  const { error } = await supabase.auth.exchangeCodeForSession(requestUrl.searchParams)
  
  if (error) {
    console.error('会话交换错误:', error)
    return NextResponse.redirect(new URL('/auth/error', requestUrl.origin))
  }

  return NextResponse.redirect(new URL('/mypage', requestUrl.origin))
}

2. 完善Supabase Auth设置

  • 登录Supabase控制台,进入Auth -> Settings;
  • 设置Site URL为http://localhost:3000(本地开发环境);
  • 确认Redirect URLs中包含http://localhost:3000/auth/callback;
  • 检查Google第三方授权的Client ID和Client Secret是否正确配置。

3. 验证Google Cloud配置

确保Google Cloud Console中OAuth客户端的授权重定向URI为https://<supabase-project-id>.supabase.co/auth/v1/callback,此URI是Google重定向到Supabase的端点,无需与你的应用回调URI一致。

4. 检查会话状态

若仍有问题,可在回调页面中添加会话检查,确认用户是否已自动登录:

// 在回调或后续页面中
const { data: { user } } = await supabase.auth.getUser()
console.log('当前用户:', user)

内容的提问来源于stack exchange,提问作者Jun Twein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:44:51