nextjs-supabase-auth

nextjs-supabase-auth

热门

Next.js App Router 与 Supabase Auth 深度集成最佳实践指南

4.3万Star
6676Fork
更新于 2026/7/15
SKILL.md
只读
名称
nextjs-supabase-auth
描述

Next.js App Router 与 Supabase Auth 深度集成最佳实践指南

Next.js + Supabase Auth

Next.js App Router 与 Supabase Auth 深度集成最佳实践指南

Capabilities

  • nextjs-auth
  • supabase-auth-nextjs
  • auth-middleware
  • auth-callback

Prerequisites

  • Required skills: nextjs-app-router, supabase-backend

Patterns

Supabase Client Setup

针对不同上下文场景配置并创建 Supabase Client 实例。

When to use: 在 Next.js 项目中设置 Auth 认证时使用

// lib/supabase/client.ts (Browser client)
'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 (Server client)
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)
})
},
},
}
)
}

Auth Middleware

在 Middleware 中保护路由访问并刷新 Session 状态。

When to use: 需要路由拦截鉴权或自动刷新 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)
})
},
},
}
)

// Refresh session if expired
const { data: { user } } = await supabase.auth.getUser()

// Protect dashboard routes
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).*)'],
}

Auth Callback Route

处理 OAuth 回调请求,将 code 换取为 Session 凭证。

When to use: 使用第三方 OAuth 登录(如 Google、GitHub 等)时使用

// 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)
}

Server Action Auth

在 Server Action 中处理认证相关逻辑。

When to use: 在服务端组件(Server Component)中处理登录、退出登录或注册时使用

// app/actions/auth.ts
'use server'
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'
import { revalidatePath } from 'next/cache'

export async function signIn(formData: FormData) {
const supabase = await createClient()
const { error } = await supabase.auth.signInWithPassword({
email: formData.get('email') as string,
password: formData.get('password') as string,
})

if (error) {
return { error: error.message }
}

revalidatePath('/', 'layout')
redirect('/dashboard')
}

export async function signOut() {
const supabase = await createClient()
await supabase.auth.signOut()
revalidatePath('/', 'layout')
redirect('/')
}

Get User in Server Component

在服务端组件中获取已认证的用户信息。

When to use: 需要在服务端直接渲染特定用户专属内容时使用

// app/dashboard/page.tsx
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'

export default async function DashboardPage() {
const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()

if (!user) {
redirect('/login')
}

return (
<div>
<h1>Welcome, {user.email}</h1>
</div>
)
}

Validation Checks

Using getSession() for Auth Checks

Severity: ERROR

Message: getSession() 不会验证 JWT。安全鉴权场景请改用 getUser()。

Fix action: 涉及到关键安全校验时,把 getSession() 替换为 getUser()

OAuth Without Callback Route

Severity: ERROR

Message: 配置了 OAuth 但未在 app/auth/callback/route.ts 添加回调路由处理。

Fix action: 创建 app/auth/callback/route.ts 以处理 OAuth 重定向

Browser Client in Server Context

Severity: ERROR

Message: 在服务端上下文中误用了浏览器端 Client。请改用 createServerClient。

Fix action: 从 @supabase/ssr 导入并使用 createServerClient

Protected Routes Without Middleware

Severity: WARNING

Message: 未找到 middleware.ts。建议添加中间件来进行路由保护。

Fix action: 创建 middleware.ts 用于防护路由和刷新 Session

Hardcoded Auth Redirect URL

Severity: WARNING

Message: 硬编码了 localhost 重定向地址。建议使用 origin 提高环境适应灵活性。

Fix action: 改用 window.location.origin 或 process.env.NEXT_PUBLIC_SITE_URL

Auth Call Without Error Handling

Severity: WARNING

Message: 执行 Auth 操作时未进行错误处理。请务必检查并处理错误信息。

Fix action: 解构 { data, error } 并补充对应的 error 处理逻辑

Auth Action Without Revalidation

Severity: WARNING

Message: Auth 操作后未调用 revalidatePath。缓存可能仍展示旧的鉴权状态。

Fix action: 在 Auth 操作完成后添加 revalidatePath('/', 'layout')

Client-Only Route Protection

Severity: WARNING

Message: 纯客户端路由保护会出现内容闪烁。建议使用中间件解决。

Fix action: 将防护逻辑移至 middleware.ts 以提升用户体验

Collaboration

Delegation Triggers

  • database|rls|queries|tables -> supabase-backend (Auth 需要数据库层支持)
  • route|page|component|layout -> nextjs-app-router (Auth 需要 Next.js 路由模式)
  • deploy|production|vercel -> vercel-deployment (Auth 需要部署配置)
  • ui|form|button|design -> frontend (Auth 需要 UI 组件)

Full Auth Stack

Skills: nextjs-supabase-auth, supabase-backend, nextjs-app-router, vercel-deployment

Workflow:

1. 数据库搭建与配置 (supabase-backend)
2. Auth 认证能力实现 (nextjs-supabase-auth)
3. 路由拦截与保护 (nextjs-app-router)
4. 部署生产环境配置 (vercel-deployment)

Protected SaaS

Skills: nextjs-supabase-auth, stripe-integration, supabase-backend

Workflow:

1. 用户身份认证 (nextjs-supabase-auth)
2. 客户数据同步 (stripe-integration)
3. 订阅权限门槛拦截 (supabase-backend)

Related Skills

Works well with: nextjs-app-router, supabase-backend

When to Use

  • 用户提及或暗示:supabase auth next
  • 用户提及或暗示:authentication next.js
  • 用户提及或暗示:login supabase
  • 用户提及或暗示:auth middleware
  • 用户提及或暗示:protected route
  • 用户提及或暗示:auth callback
  • 用户提及或暗示:session management

Limitations

  • 仅当任务明确符合上述描述的功能范围时才使用此 Skill。
  • 切勿将此输出替代特定环境下的实际验证、测试或专家评审。
  • 若缺少必要的输入、权限、安全边界或验收标准,需立即暂停并向用户确认。