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

NextJS集成Supabase报错:TypeError: supabaseClient.auth.getSession不是函数

解决Supabase Auth Helper集成NextJS的报错及未登录跳转问题

一、解决TypeError: supabaseClient.auth.getSession is not a function报错

1. 对齐依赖版本

@supabase/auth-helpers-nextjs要求配合**v2.x版本的@supabase/supabase-js**使用,v1版本的supabase-js没有getSession方法。执行命令更新依赖:

npm install @supabase/supabase-js@^2.x.x @supabase/auth-helpers-nextjs @supabase/auth-helpers-react

2. 补全_app.js关键代码

你的_app.js缺少必要的导入语句,修正后代码如下:

import { useState } from 'react'
import { useRouter } from 'next/router'
// 新增auth helper相关导入
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs'
import { SessionContextProvider } from '@supabase/auth-helpers-react'

import '../styles/global.css'
import ProfileContext from '../utils/context/ProfileContext'
import useProfile from '../utils/hooks/useProfile'
import ProtectedRoutes from '../utils/constants/rutas/protectedRoutes'

const MyApp = ({ Component, pageProps }) => {
  const [supabaseClient] = useState(() => createBrowserSupabaseClient())
  
  return (
    <SessionContextProvider
      supabaseClient={supabaseClient}
      initialSession={pageProps.initialSession}
    >
      <ProfileContext.Provider value={useProfile()}>
        <Component {...pageProps} />
      </ProfileContext.Provider>
    </SessionContextProvider>
  )
}
export default MyApp

3. 统一Supabase客户端实例

不要混用自定义supabase实例和auth helper创建的实例,修改index.js的服务端逻辑:

import { useState } from "react"
import { useSession } from '@supabase/auth-helpers-react'
import Layout from "../layout/Layout"
import List from "../components/List"
import Empty from "../components/Empty"
// 移除自定义supabase实例导入
// import { supabase } from "../utils/supabaseClient"

const Index = ({ allData }) => {
  // 使用auth helper钩子获取session
  const { session } = useSession()

  return (
    <Layout>
      {allData.length ? <List allData={allData} /> : <Empty />}
    </Layout>
  );
}

export default Index

export async function getServerSideProps(ctx) {
  // 使用auth helper创建服务端客户端
  const supabase = createServerSupabaseClient(ctx)
  let { data: receptions, error } = await supabase
        .from('receptions')
        .select('*')
        .order('id', { ascending: false })
  if (error) throw error
  
  return {
    props: {
      allData: receptions,
      // 传递初始session给全局上下文
      initialSession: (await supabase.auth.getSession()).data.session
    },
  };
}

二、实现未登录自动跳转功能

方法1:全局路由守卫(_app.js中实现)

封装全局组件监听session状态,自动跳转未登录用户:

import { useState, useEffect } from 'react'
import { useRouter } from 'next/router'
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs'
import { SessionContextProvider, useSession } from '@supabase/auth-helpers-react'

import '../styles/global.css'
import ProfileContext from '../utils/context/ProfileContext'
import useProfile from '../utils/hooks/useProfile'
import ProtectedRoutes from '../utils/constants/rutas/protectedRoutes'

// 登录守卫组件
const AuthGuard = ({ children }) => {
  const { session } = useSession()
  const router = useRouter()

  useEffect(() => {
    const isProtected = ProtectedRoutes.includes(router.pathname)
    // 未登录且访问受保护路由时跳转登录页
    if (!session && isProtected) {
      router.push('/login') // 替换为你的登录页路由
    }
  }, [session, router])

  return children
}

const MyApp = ({ Component, pageProps }) => {
  const [supabaseClient] = useState(() => createBrowserSupabaseClient())
  
  return (
    <SessionContextProvider
      supabaseClient={supabaseClient}
      initialSession={pageProps.initialSession}
    >
      <AuthGuard>
        <ProfileContext.Provider value={useProfile()}>
          <Component {...pageProps} />
        </ProfileContext.Provider>
      </AuthGuard>
    </SessionContextProvider>
  )
}
export default MyApp

方法2:单个页面服务端检查

在需要保护的页面的getServerSideProps中直接校验session:

export async function getServerSideProps(ctx) {
  const supabase = createServerSupabaseClient(ctx)
  const { data: { session } } = await supabase.auth.getSession()

  // 未登录则重定向到登录页
  if (!session) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    }
  }

  // 已登录则获取页面数据
  let { data: receptions, error } = await supabase
        .from('receptions')
        .select('*')
        .order('id', { ascending: false })
  if (error) throw error
  
  return {
    props: {
      allData: receptions,
      initialSession: session
    },
  };
}

内容的提问来源于stack exchange,提问作者Cesar Mejias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:15:34