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

在Next.js中用Supabase创建私有路由:解决getServerSideProps冲突问题

在Next.js中结合Supabase实现私有路由(兼容getServerSideProps)

你不需要使用getInitialProps,直接在getServerSideProps中集成Supabase的身份验证逻辑即可——这是Next.js Pages Router下实现私有路由最直接且符合官方推荐的方式。以下是两种可行方案:

方案1:在getServerSideProps中直接做权限校验

利用getServerSideProps的服务端运行特性,每次请求时先验证用户会话,未登录则重定向到登录页,登录成功后再获取页面所需数据。

示例代码:

import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'

export async function getServerSideProps(context) {
  // 初始化服务端Supabase客户端(需依赖auth-helpers-nextjs包)
  const supabase = createServerComponentClient({ cookies }, context)
  
  // 获取当前用户会话
  const { data: { session } } = await supabase.auth.getSession()

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

  // 会话有效,执行你的数据获取逻辑
  const { data: userProfile, error } = await supabase
    .from('profiles')
    .select('*')
    .eq('user_id', session.user.id)
    .single()

  if (error) {
    // 处理数据获取失败的情况,比如重定向到错误页
    return {
      redirect: {
        destination: '/error',
        permanent: false,
      },
    }
  }

  // 将数据传递给页面组件
  return {
    props: { userProfile },
  }
}

// 私有页面组件
export default function PrivateDashboard({ userProfile }) {
  return (
    <div>
      <h2>欢迎访问私有仪表盘</h2>
      <p>用户名:{userProfile.username}</p>
    </div>
  )
}

方案2:用Next.js中间件统一处理私有路由

如果需要保护大量页面,推荐使用Next.js Middleware实现全局权限校验,避免在每个页面的getServerSideProps中重复写校验逻辑。

  1. 在项目根目录创建middleware.js文件:
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs'
import { NextResponse } from 'next/server'

export async function middleware(req) {
  const res = NextResponse.next()
  // 初始化中间件专用的Supabase客户端
  const supabase = createMiddlewareClient({ req, res })

  // 获取用户会话
  const { data: { session } } = await supabase.auth.getSession()

  // 定义需要保护的路由规则
  const isProtectedRoute = req.nextUrl.pathname.startsWith('/dashboard') || 
                          req.nextUrl.pathname.startsWith('/profile')

  // 未登录且访问私有路由时,重定向到登录页(附带原路径,方便登录后跳转回来)
  if (isProtectedRoute && !session) {
    const redirectUrl = new URL('/login', req.url)
    redirectUrl.searchParams.set('redirectTo', req.nextUrl.pathname)
    return NextResponse.redirect(redirectUrl)
  }

  return res
}

// 指定中间件生效的路由范围
export const config = {
  matcher: ['/dashboard/:path*', '/profile/:path*'],
}
  1. 页面的getServerSideProps只需专注于数据获取:
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'

export async function getServerSideProps(context) {
  const supabase = createServerComponentClient({ cookies }, context)
  const { data: { session } } = await supabase.auth.getSession()

  // 此时中间件已确保session存在,可直接获取数据
  const { data: userPosts } = await supabase
    .from('posts')
    .select('*')
    .eq('author_id', session.user.id)

  return {
    props: { userPosts },
  }
}

export default function UserPosts({ userPosts }) {
  return (
    <div>
      <h2>我的文章</h2>
      {userPosts.map(post => (
        <div key={post.id}>{post.title}</div>
      ))}
    </div>
  )
}

关键说明

  • 无需使用getInitialProps:它是Next.js旧版API,官方更推荐使用getServerSideProps(服务端渲染)或静态生成方案,且getInitialProps会在客户端和服务端都运行,不如getServerSideProps适合做服务端权限校验。
  • 依赖Supabase Auth Helpers:使用@supabase/auth-helpers-nextjs包可以简化服务端/中间件中Supabase客户端的初始化和会话管理,避免手动处理cookie。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 09:21:35