如何在 Next.js App Router 中快速集成 Supabase Auth 认证

解决 Next.js 应用在引入第三方认证时的配置痛点:通过规范化的 Client 实例化、中间件路由拦截和 Server Actions 处理,快速搭建一个安全且高性能的身份认证系统。

为什么需要这个技能

在 Next.js 的 App Router 架构中,代码分布在服务端组件(Server Components)、客户端组件(Client Components)和中间件(Middleware)之间。如果认证配置不统一,会导致 Session 状态同步失败、页面闪烁或严重的安全性漏洞。

本技能提供了一套标准的集成模式,利用 @supabase/ssr 库确保在所有运行环境下都能正确获取用户身份,并解决了 OAuth 登录后的回调跳转、Session 自动刷新等核心工程问题。

适用场景

  • 构建需要登录权限的 SaaS 应用或管理后台。
  • 需要实现 Google、GitHub 等第三方 OAuth 社交登录。
  • 需要在服务端组件中直接拦截未登录用户并重定向至登录页。
  • 需要在 Middleware 层实现全局的路由权限控制。

核心工作流

1. 配置多环境客户端

针对不同上下文创建 Supabase Client,确保 Cookie 在服务端与浏览器端同步。

// lib/supabase/client.ts (浏览器端)
'use client'
import { createBrowserClient } from '@supabase/ssr'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  )
}

// lib/supabase/server.ts (服务端)
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'

export async function createClient() {
  const cookieStore = await cookies()
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() { return cookieStore.getAll() },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) => {
            cookieStore.set(name, value, options)
          })
        },
      },
    }
  )
}

2. 实现路由保护中间件

middleware.ts 中统一处理 Session 刷新和私有路由拦截。

// middleware.ts
import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
  let response = NextResponse.next({ request })
  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() { return request.cookies.getAll() },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) => {
            response.cookies.set(name, value, options)
          })
        },
      },
    }
  )

  const { data: { user } } = await supabase.auth.getUser()

  if (request.nextUrl.pathname.startsWith('/dashboard') && !user) {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  return response
}

export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
}

3. 处理 OAuth 回调与 Server Actions

创建专用的回调路由处理 OAuth 换码流程,并使用 Server Actions 处理登录登出逻辑。

// app/auth/callback/route.ts
import { createClient } from '@/lib/supabase/server'
import { NextResponse } from 'next/server'

export async function GET(request: Request) {
  const { searchParams, origin } = new URL(request.url)
  const code = searchParams.get('code')
  const next = searchParams.get('next') ?? '/'

  if (code) {
    const supabase = await createClient()
    const { error } = await supabase.auth.exchangeCodeForSession(code)
    if (!error) return NextResponse.redirect(`${origin}${next}`)
  }
  return NextResponse.redirect(`${origin}/auth/error`)
}

下载和安装

下载 nextjs-supabase-auth 中文版 Skill ZIP

解压后将目录放入你的 AI 工具 skills 文件夹,重启工具后即可使用。具体路径参考内附的 USAGE.zh.md

你可能还需要

暂无推荐