关于 nextjs-supabase-auth
为 Next.js App Router 项目提供 Supabase Auth 集成模式,面向实现登录、会话管理和受保护路由的开发者。内容包含客户端配置、OAuth 回调及安全检查。
主要功能
- 01配置浏览器与服务端客户端
- 02中间件刷新会话并保护路由
- 03处理 OAuth 回调
- 04通过 Server Actions 执行认证
- 05检查常见认证错误
适用场景
- 01为 Next.js 应用添加 Supabase 登录
- 02刷新会话并限制仪表板访问
- 03处理 OAuth 登录回调
- 04审查服务端认证与重定向
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill nextjs-supabase-auth安装后在 Claude Code 中输入/nextjs-supabase-auth确认已加载。
详细介绍
Next.js + Supabase Auth
将 Supabase Auth 与 Next.js App Router 专业集成
能力
- nextjs-auth
- supabase-auth-nextjs
- auth-middleware
- auth-callback
前置条件
- 所需技能:nextjs-app-router、supabase-backend
模式
Supabase 客户端设置
为不同上下文创建配置正确的 Supabase 客户端
适用场景:在 Next.js 项目中设置身份验证
// 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) { // 此辅助函数用于可以写入 Cookie 的 Route Handler/Server Action。 // 在 Server Component 中使用官方只读客户端模式, // 并在 middleware/proxy 中刷新会话;不要在此处尝试写入 Cookie。 cookiesToSet.forEach(({ name, value, options }) => cookieStore.set(name, value, options)) }, }, } ) }
身份验证中间件
在中间件中保护路由并刷新会话
适用场景:需要保护路由或刷新会话
// 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 }) => request.cookies.set(name, value)) response = NextResponse.next({ request }) cookiesToSet.forEach(({ name, value, options }) => response.cookies.set(name, value, options)) }, }, } )
// 如果会话已过期,则刷新会话 const { data: { user } } = await supabase.auth.getUser()
// 保护 dashboard 路由 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).*)'], }
身份验证回调路由
处理 OAuth 回调并将代码交换为会话
适用场景:使用 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 candidate = searchParams.get('next') ?? '/' const next = candidate.startsWith('/') && !candidate.startsWith('//') && !candidate.includes('\') ? candidate : '/'
if (code) { const supabase = await createClient() const { error } = await supabase.auth.exchangeCodeForSession(code) if (!error) { return NextResponse.redirect(new URL(next, process.env.APP_ORIGIN!)) // 已验证的可信部署源 } }
return NextResponse.redirect(${origin}/auth/error)
}
服务端操作中的认证
在服务端操作中处理认证操作
何时使用:在服务端组件中执行登录、登出或注册
// 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('/') }
在服务端组件中获取用户
在服务端组件中访问已认证的用户
何时使用:在服务端渲染特定于用户的内容
// 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 (
Welcome, {user.email}
校验检查
使用 getSession() 进行认证检查
严重程度:ERROR
消息:getSession() 不会验证 JWT。请使用 getUser() 进行安全的认证检查。
修复操作:将 getSession() 替换为 getUser() 以用于安全关键的检查
OAuth 缺少回调路由
严重程度:ERROR
消息:使用了 OAuth 但缺少 app/auth/callback/route.ts 处的回调路由
修复操作:创建 app/auth/callback/route.ts 以处理 OAuth 重定向
在服务端上下文中使用浏览器客户端
严重程度:ERROR
消息:在服务端上下文中使用了浏览器客户端。请改用 createServerClient。
修复操作:从 @supabase/ssr 导入并使用 createServerClient
受保护路由缺少中间件
严重程度:WARNING
消息:未找到 middleware.ts。考虑添加中间件以保护路由。
修复操作:创建 middleware.ts 以保护路由并刷新会话
硬编码的认证重定向 URL
严重程度:WARNING
消息:硬编码的 localhost 重定向。使用 origin 以获得环境灵活性。
修复操作:使用 window.location.origin 或 process.env.NEXT_PUBLIC_SITE_URL
认证调用缺少错误处理
严重程度:WARNING
消息:认证操作缺少错误处理。请始终检查错误。
修复操作:解构 { data, error } 并处理错误情况
认证操作缺少重新验证
严重程度:WARNING
消息:认证操作缺少 revalidatePath。缓存可能显示过时的认证状态。
修复操作:在认证操作后添加 revalidatePath('/', 'layout')
仅客户端的路由保护
严重程度:WARNING
消息:客户端路由保护会显示内容闪烁。请使用中间件。
修复操作:将保护移至 middleware.ts 以获得更好的用户体验
协作
委托触发条件
- database|rls|queries|tables -> supabase-backend(认证需要数据库层)
- route|page|component|layout -> nextjs-app-router(认证需要 Next.js 模式)
- deploy|production|vercel -> vercel-deployment(认证需要部署配置)
- ui|form|button|design -> frontend(认证需要 UI 组件)
完整的认证技术栈
技能:nextjs-supabase-auth、supabase-backend、nextjs-app-router、vercel-deployment
工作流:
1. Database setup (supabase-backend)
2. Auth implementation (nextjs-supabase-auth)
3. Route protection (nextjs-app-router)
4. Deployment config (vercel-deployment)
受保护的 SaaS
技能:nextjs-supabase-auth、stripe-integration、supabase-backend
工作流:
1. User authentication (nextjs-supabase-auth)
2. Customer sync (stripe-integration)
3. Subscription gating (supabase-backend)
相关技能
可良好配合:nextjs-app-router、supabase-backend
适用场景
- 用户提及或暗示:supabase auth next
- 用户提及或暗示:authentication next.js
- 用户提及或暗示:login supabase
- 用户提及或暗示:auth middleware
- 用户提及或暗示:protected route
- 用户提及或暗示:auth callback
- 用户提及或暗示:session management
限制
- 仅当任务明确符合上述范围时,才使用此技能。
- 不要将输出视为环境特定验证、测试或专家审查的替代品。
- 如果缺少必需的输入、权限、安全边界或成功标准,请暂停并要求澄清。
这些是独立文件片段,并非完整的身份验证部署。请先配置并验证可信的 APP_ORIGIN、回调允许列表以及确切的 Next.js/Supabase 版本。服务器组件无法写入 cookie;请使用当前官方的特定上下文辅助工具,而不要抑制任意刷新失败。请在返回的重定向中保留已刷新的 cookie。中间件不是唯一的授权层:请在每条服务器数据/操作路径上验证会话/声明以及租户/资源权限,并强制执行 RLS。切勿向浏览器公开服务角色密钥。请参阅 Supabase 服务端客户端指南。