nextjs-supabase-auth
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNext.js + Supabase Auth
Next.js + Supabase Auth
Expert integration of Supabase Auth with Next.js App Router
Supabase Auth与Next.js App Router的专业集成方案
Capabilities
功能特性
- nextjs-auth
- supabase-auth-nextjs
- auth-middleware
- auth-callback
- nextjs-auth
- supabase-auth-nextjs
- auth-middleware
- auth-callback
Prerequisites
前置要求
- Required skills: nextjs-app-router, supabase-backend
- 必备技能:nextjs-app-router, supabase-backend
Patterns
实现模式
Supabase Client Setup
Supabase客户端配置
Create properly configured Supabase clients for different contexts
When to use: Setting up auth in a Next.js project
// 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)
})
},
},
}
)
}
为不同上下文创建配置正确的Supabase客户端
适用场景:在Next.js项目中设置认证功能
// 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)
})
},
},
}
)
}
Auth Middleware
认证中间件
Protect routes and refresh sessions in middleware
When to use: You need route protection or session refresh
// 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).*)'],
}
在中间件中保护路由并刷新会话
适用场景:需要路由保护或会话刷新时
// 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).*)'],
}
Auth Callback Route
认证回调路由
Handle OAuth callback and exchange code for session
When to use: Using OAuth providers (Google, GitHub, etc.)
// 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处理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 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/errorServer Action Auth
服务端动作认证
Handle auth operations in Server Actions
When to use: Login, logout, or signup from Server Components
// 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('/')
}
在Server Actions中处理认证操作
适用场景:从Server Components中处理登录、登出或注册
// 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
在Server Component中获取用户
Access the authenticated user in Server Components
When to use: Rendering user-specific content server-side
// 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>
)
}
在Server Components中访问已认证用户
适用场景:服务端渲染用户专属内容时
// 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
使用getSession()进行认证检查
Severity: ERROR
Message: getSession() doesn't verify the JWT. Use getUser() for secure auth checks.
Fix action: Replace getSession() with getUser() for security-critical checks
严重程度:错误
提示信息:getSession()不会验证JWT。请使用getUser()进行安全的认证检查。
修复操作:在安全关键的检查中替换getSession()为getUser()
OAuth Without Callback Route
缺少回调路由的OAuth集成
Severity: ERROR
Message: Using OAuth but missing callback route at app/auth/callback/route.ts
Fix action: Create app/auth/callback/route.ts to handle OAuth redirects
严重程度:错误
提示信息:使用了OAuth但缺少app/auth/callback/route.ts回调路由
修复操作:创建app/auth/callback/route.ts来处理OAuth重定向
Browser Client in Server Context
在服务端上下文使用浏览器客户端
Severity: ERROR
Message: Browser client used in server context. Use createServerClient instead.
Fix action: Import and use createServerClient from @supabase/ssr
严重程度:错误
提示信息:在服务端上下文使用了浏览器客户端。请改用createServerClient。
修复操作:从@supabase/ssr导入并使用createServerClient
Protected Routes Without Middleware
无中间件的受保护路由
Severity: WARNING
Message: No middleware.ts found. Consider adding middleware for route protection.
Fix action: Create middleware.ts to protect routes and refresh sessions
严重程度:警告
提示信息:未找到middleware.ts。考虑添加中间件以实现路由保护。
修复操作:创建middleware.ts来保护路由并刷新会话
Hardcoded Auth Redirect URL
硬编码的认证重定向URL
Severity: WARNING
Message: Hardcoded localhost redirect. Use origin for environment flexibility.
Fix action: Use window.location.origin or process.env.NEXT_PUBLIC_SITE_URL
严重程度:警告
提示信息:硬编码了localhost重定向地址。请使用origin以适配不同环境。
修复操作:使用window.location.origin或process.env.NEXT_PUBLIC_SITE_URL
Auth Call Without Error Handling
无错误处理的认证调用
Severity: WARNING
Message: Auth operation without error handling. Always check for errors.
Fix action: Destructure { data, error } and handle error case
严重程度:警告
提示信息:认证操作未添加错误处理。请始终检查错误。
修复操作:解构{ data, error }并处理错误情况
Auth Action Without Revalidation
无重验证的认证动作
Severity: WARNING
Message: Auth action without revalidatePath. Cache may show stale auth state.
Fix action: Add revalidatePath('/', 'layout') after auth operations
严重程度:警告
提示信息:认证动作未添加revalidatePath。缓存可能显示过期的认证状态。
修复操作:在认证操作后添加revalidatePath('/', 'layout')
Client-Only Route Protection
仅客户端的路由保护
Severity: WARNING
Message: Client-side route protection shows flash of content. Use middleware.
Fix action: Move protection to middleware.ts for better UX
严重程度:警告
提示信息:客户端路由保护会出现内容闪烁。请使用中间件。
修复操作:将保护逻辑移至middleware.ts以获得更好的用户体验
Collaboration
协作指南
Delegation Triggers
任务触发条件
- database|rls|queries|tables -> supabase-backend (Auth needs database layer)
- route|page|component|layout -> nextjs-app-router (Auth needs Next.js patterns)
- deploy|production|vercel -> vercel-deployment (Auth needs deployment config)
- ui|form|button|design -> frontend (Auth needs UI components)
- 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组件)
Full Auth Stack
完整认证栈
Skills: nextjs-supabase-auth, supabase-backend, nextjs-app-router, vercel-deployment
Workflow:
1. Database setup (supabase-backend)
2. Auth implementation (nextjs-supabase-auth)
3. Route protection (nextjs-app-router)
4. Deployment config (vercel-deployment)所需技能:nextjs-supabase-auth, supabase-backend, nextjs-app-router, vercel-deployment
工作流程:
1. 数据库设置(supabase-backend)
2. 认证实现(nextjs-supabase-auth)
3. 路由保护(nextjs-app-router)
4. 部署配置(vercel-deployment)Protected SaaS
受保护的SaaS应用
Skills: nextjs-supabase-auth, stripe-integration, supabase-backend
Workflow:
1. User authentication (nextjs-supabase-auth)
2. Customer sync (stripe-integration)
3. Subscription gating (supabase-backend)所需技能:nextjs-supabase-auth, stripe-integration, supabase-backend
工作流程:
1. 用户认证(nextjs-supabase-auth)
2. 客户同步(stripe-integration)
3. 订阅权限控制(supabase-backend)Related Skills
相关技能
Works well with: ,
nextjs-app-routersupabase-backend适配技能:,
nextjs-app-routersupabase-backendWhen to Use
使用场景
- User mentions or implies: supabase auth next
- User mentions or implies: authentication next.js
- User mentions or implies: login supabase
- User mentions or implies: auth middleware
- User mentions or implies: protected route
- User mentions or implies: auth callback
- User mentions or implies: session management
- 用户提及或涉及:supabase auth next
- 用户提及或涉及:authentication next.js
- 用户提及或涉及:login supabase
- 用户提及或涉及:auth middleware
- 用户提及或涉及:protected route
- 用户提及或涉及:auth callback
- 用户提及或涉及:session management
Limitations
局限性
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
- 仅当任务明确符合上述描述的范围时使用此技能。
- 请勿将输出内容替代环境特定的验证、测试或专家评审。
- 如果缺少必要的输入、权限、安全边界或成功标准,请停止操作并请求澄清。