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

Next.js中NEXT_PUBLIC变量异常致Supabase 403错误排查

Next.js中Supabase createClient()返回403 Invalid API key,但同一密钥fetch正常的问题排查

问题背景

基于Next.js开发Supabase应用时遇到异常:所有通过@supabase/supabase-js的createClient()发起的请求均返回403 Forbidden,提示“Invalid API key”,但同一密钥在浏览器控制台用fetch()直接调用Supabase API却能正常返回数据。

配置与代码

.env.local配置:

NEXT_PUBLIC_SUPABASE_URL=https://rgfqebiuevnwfetdfaoh.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...

lib/supabase.ts初始化代码:

import { createClient } from '@supabase/supabase-js'

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

已尝试的排查步骤

  • 确认.env.local在项目根目录,NEXT_PUBLIC_前缀正确
  • 多次重启开发服务,终端打印环境变量显示正常
  • 硬编码URL和密钥到createClient(),问题依旧
  • 禁用表RLS、验证RLS策略、用anon角色执行直接SQL查询均正常
  • 尝试旧版JWT密钥和新版可发布密钥
  • 部署到Netlify后问题未解决

版本信息

  • Next.js 16.2.6
  • @supabase/supabase-js 2.106.1
  • pnpm 11.1.3
  • Node v24.11.1

可能的原因与解决方法

1. Supabase-js请求头格式或全局拦截问题

Supabase-js默认会将anon key放在Authorization: Bearer <key>请求头中,而你用fetch()测试时可能使用的是apikey查询参数(比如https://<project>.supabase.co/rest/v1/table?apikey=<your-key>)。

排查与修复:

  • 打开浏览器开发者工具Network面板,查看Supabase-js发起的请求的Authorization头,确认密钥完整无截断,格式为Bearer <你的完整anon key>
  • 若差异在于参数传递方式,可强制Supabase-js使用查询参数传递密钥:
    export const supabase = createClient(
      process.env.NEXT_PUBLIC_SUPABASE_URL!,
      process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
      {
        global: {
          headers: {
            apikey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
          }
        }
      }
    )
    

2. Next.js App Router与Supabase-js初始化时机冲突

Next.js 16的App Router对客户端组件的状态管理和实例初始化有严格要求,全局导出的supabase实例可能因hydration或生命周期问题导致请求异常。

解决方法:
改用@supabase/ssr包的createBrowserClient专门初始化浏览器端实例,避免全局实例问题:

  1. 安装依赖:
    pnpm add @supabase/ssr
    
  2. 修改lib/supabase.ts:
    import { createBrowserClient } from '@supabase/ssr'
    
    export const createSupabaseClient = () =>
      createBrowserClient(
        process.env.NEXT_PUBLIC_SUPABASE_URL!,
        process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
      )
    
  3. 在客户端组件中动态创建实例:
    'use client'
    import { createSupabaseClient } from '@/lib/supabase'
    
    export default function MyComponent() {
      const supabase = createSupabaseClient()
    
      // 后续使用supabase实例发起请求
      return <div>...</div>
    }
    

3. 版本兼容性问题

Supabase-js 2.106.1是较新版本,可能与Next.js 16存在未适配的兼容性问题。

解决方法:
降级Supabase-js到稳定版本,比如2.99.3:

pnpm add @supabase/supabase-js@2.99.3

4. 全局Fetch被修改

Next.js 16默认会对fetch进行增强(缓存、重试等),若项目中有全局配置或第三方库修改了fetch行为,可能影响Supabase-js的请求。

排查步骤:

  • 检查next.config.js中的experimental.fetchCache或headers配置,是否有覆盖请求头的设置
  • 排查是否有第三方库(如axios拦截器、身份验证库)修改了全局fetch或请求头

内容的提问来源于stack exchange,提问作者Muchi Bari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 07:34:54