mcpField
N
nextjs-supabase-auth

nextjs-supabase-auth

github.com/sickn33开发48.7k6.6k 次安装今天更新
代码仓库

关于 nextjs-supabase-auth

为 Next.js App Router 项目提供 Supabase Auth 集成模式,面向实现登录、会话管理和受保护路由的开发者。内容包含客户端配置、OAuth 回调及安全检查。

主要功能

  1. 01配置浏览器与服务端客户端
  2. 02中间件刷新会话并保护路由
  3. 03处理 OAuth 回调
  4. 04通过 Server Actions 执行认证
  5. 05检查常见认证错误

适用场景

  1. 01为 Next.js 应用添加 Supabase 登录
  2. 02刷新会话并限制仪表板访问
  3. 03处理 OAuth 登录回调
  4. 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 服务端客户端指南。

评论

支持 Markdown