nextjs-supabase-auth

nextjs-supabase-auth

热门

Expert integration of Supabase Auth with Next.js App Router

4.3万Star
6676Fork
更新于 2026/7/15
请求的译文尚未完成,当前显示原始英文。
SKILL.md
readonly只读
name
nextjs-supabase-auth
description

Expert integration of Supabase Auth with Next.js App Router

Next.js + Supabase Auth

Expert integration of Supabase Auth with Next.js App Router

Capabilities

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

Prerequisites

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

Patterns

Supabase Client Setup

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

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).*)'],
}

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

Server 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('/')
}

Get User in 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>
)
}

Validation Checks

Using getSession() for Auth Checks

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

OAuth Without Callback Route

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

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

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

Hardcoded Auth Redirect 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

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

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

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

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)

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)

Protected 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)

Related Skills

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

When 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

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.