supabase-auth-ssr-setup

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Supabase Auth SSR Setup

Supabase Auth SSR 配置指南

Overview

概述

Configure Supabase Authentication for Next.js App Router with server-side rendering (SSR), secure cookie-based sessions, middleware protection, and complete authentication flows.
为Next.js App Router配置Supabase认证,包含服务端渲染(SSR)、基于安全Cookie的会话、中间件保护及完整的认证流程。

Installation and Configuration Steps

安装与配置步骤

1. Install Dependencies

1. 安装依赖

Install Supabase SSR package for Next.js:
bash
npm install @supabase/supabase-js @supabase/ssr
为Next.js安装Supabase SSR包:
bash
npm install @supabase/supabase-js @supabase/ssr

2. Create Supabase Client Utilities

2. 创建Supabase客户端工具

Create three client configurations for different contexts (browser, server, middleware):
File:
lib/supabase/client.ts
(Browser client)
Use the template from
assets/supabase-client.ts
. This client:
  • Runs only in browser context
  • Uses secure cookies for session storage
  • Automatically refreshes tokens
File:
lib/supabase/server.ts
(Server component client)
Use the template from
assets/supabase-server.ts
. This client:
  • Creates server-side Supabase client with cookie access
  • Used in Server Components and Server Actions
  • Provides read-only cookie access for security
File:
lib/supabase/middleware.ts
(Middleware client)
Use the template from
assets/supabase-middleware.ts
. This client:
  • Used in Next.js middleware for route protection
  • Can update cookies in responses
  • Refreshes sessions on route navigation
针对不同上下文(浏览器、服务端、中间件)创建三种客户端配置:
文件:
lib/supabase/client.ts
(浏览器端客户端)
使用
assets/supabase-client.ts
中的模板。该客户端:
  • 仅在浏览器上下文运行
  • 使用安全Cookie存储会话
  • 自动刷新令牌
文件:
lib/supabase/server.ts
(服务端组件客户端)
使用
assets/supabase-server.ts
中的模板。该客户端:
  • 创建可访问Cookie的服务端Supabase客户端
  • 用于服务端组件和服务端操作(Server Actions)
  • 提供只读Cookie访问以保障安全
文件:
lib/supabase/middleware.ts
(中间件客户端)
使用
assets/supabase-middleware.ts
中的模板。该客户端:
  • 用于Next.js中间件实现路由保护
  • 可在响应中更新Cookie
  • 路由导航时刷新会话

3. Configure Environment Variables

3. 配置环境变量

Add Supabase credentials to
.env.local
:
env
NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
Get these values from your Supabase project settings under API.
Security note: The anon key is safe to expose publicly. Real security comes from Row Level Security (RLS) policies in your database.
将Supabase凭据添加到
.env.local
env
NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
可从Supabase项目设置的API页面获取这些值。
安全说明:匿名密钥可以安全地公开暴露。真正的安全性来自数据库中的行级安全(RLS)策略。

4. Create Middleware for Route Protection

4. 创建路由保护中间件

Create
middleware.ts
in project root using the template from
assets/middleware.ts
. This middleware:
  • Refreshes Supabase session on every request
  • Protects routes matching specified patterns
  • Redirects unauthenticated users to login
  • Allows public routes to bypass authentication
Configure protected routes by adjusting the matcher pattern:
typescript
export const config = {
  matcher: [
    '/dashboard/:path*',
    '/settings/:path*',
    '/api/protected/:path*',
  ],
};
使用
assets/middleware.ts
中的模板在项目根目录创建
middleware.ts
。该中间件:
  • 每次请求时刷新Supabase会话
  • 保护匹配指定规则的路由
  • 将未认证用户重定向至登录页
  • 允许公开路由绕过认证
通过调整匹配规则配置受保护路由:
typescript
export const config = {
  matcher: [
    '/dashboard/:path*',
    '/settings/:path*',
    '/api/protected/:path*',
  ],
};

5. Create Authentication Utilities

5. 创建认证工具函数

Create helper functions for common auth operations using templates from
assets/auth-utils.ts
:
Get current user server-side:
typescript
import { getCurrentUser } from '@/lib/auth/utils';

const user = await getCurrentUser();
Require authentication:
typescript
import { requireAuth } from '@/lib/auth/utils';

const user = await requireAuth(); // Throws error if not authenticated
Get session:
typescript
import { getSession } from '@/lib/auth/utils';

const session = await getSession();
These utilities simplify authentication checks in Server Components and Server Actions.
使用
assets/auth-utils.ts
中的模板创建通用认证操作的辅助函数:
服务端获取当前用户
typescript
import { getCurrentUser } from '@/lib/auth/utils';

const user = await getCurrentUser();
强制认证
typescript
import { requireAuth } from '@/lib/auth/utils';

const user = await requireAuth(); // 未认证时抛出错误
获取会话
typescript
import { getSession } from '@/lib/auth/utils';

const session = await getSession();
这些工具简化了服务端组件和服务端操作中的认证检查。

6. Create Logout Server Action

6. 创建登出服务端操作

Create
app/actions/auth.ts
using the template from
assets/auth-actions.ts
. This provides:
Logout action:
  • Clears Supabase session
  • Removes auth cookies
  • Redirects to home page
Use in client components:
typescript
import { logout } from '@/app/actions/auth';

<button onClick={() => logout()}>
  Sign Out
</button>
使用
assets/auth-actions.ts
中的模板创建
app/actions/auth.ts
。该文件提供:
登出操作
  • 清除Supabase会话
  • 删除认证Cookie
  • 重定向至首页
在客户端组件中使用:
typescript
import { logout } from '@/app/actions/auth';

<button onClick={() => logout()}>
  退出登录
</button>

7. Create Login Page

7. 创建登录页面

Create
app/login/page.tsx
using the template from
assets/login-page.tsx
. This page:
  • Provides email/password login form
  • Handles magic link authentication
  • Supports OAuth providers (Google, GitHub, etc.)
  • Redirects authenticated users
  • Shows error messages
Customize the login page:
  • Add your branding and styling
  • Enable/disable OAuth providers
  • Add password reset link
  • Include sign-up link
使用
assets/login-page.tsx
中的模板创建
app/login/page.tsx
。该页面:
  • 提供邮箱/密码登录表单
  • 处理魔法链接认证
  • 支持OAuth提供商(Google、GitHub等)
  • 已认证用户自动重定向
  • 显示错误信息
自定义登录页面:
  • 添加品牌标识和样式
  • 启用/禁用OAuth提供商
  • 添加密码重置链接
  • 包含注册链接

8. Create Protected Route Example

8. 创建受保护路由示例

Create a protected dashboard page at
app/dashboard/page.tsx
using the template from
assets/dashboard-page.tsx
. This demonstrates:
  • Using
    requireAuth()
    to protect routes
  • Displaying user information
  • Including logout functionality
  • Server-side authentication check
使用
assets/dashboard-page.tsx
中的模板在
app/dashboard/page.tsx
创建受保护的仪表盘页面。该示例展示:
  • 使用
    requireAuth()
    保护路由
  • 显示用户信息
  • 包含登出功能
  • 服务端认证检查

9. Set Up Callback Route for OAuth

9. 配置OAuth回调路由

If using OAuth providers, create
app/auth/callback/route.ts
using the template from
assets/auth-callback-route.ts
. This handler:
  • Exchanges OAuth code for session
  • Sets secure session cookies
  • Redirects to intended destination
  • Handles OAuth errors
Configure OAuth in Supabase dashboard:
  1. Go to Authentication > Providers
  2. Enable desired providers (Google, GitHub, etc.)
  3. Add redirect URL:
    https://your-domain.com/auth/callback
若使用OAuth提供商,使用
assets/auth-callback-route.ts
中的模板创建
app/auth/callback/route.ts
。该处理器:
  • 用OAuth代码交换会话
  • 设置安全会话Cookie
  • 重定向至目标页面
  • 处理OAuth错误
在Supabase控制台配置OAuth:
  1. 进入认证 > 提供商
  2. 启用所需提供商(Google、GitHub等)
  3. 添加重定向URL:
    https://your-domain.com/auth/callback

Authentication Flow

认证流程

Login Flow

登录流程

  1. User visits
    /login
  2. User enters credentials or clicks OAuth
  3. Supabase authenticates and sets session cookie
  4. User redirected to dashboard or intended page
  5. Middleware validates session on protected routes
  1. 用户访问
    /login
  2. 用户输入凭据或点击OAuth按钮
  3. Supabase完成认证并设置会话Cookie
  4. 用户被重定向至仪表盘或目标页面
  5. 中间件在受保护路由上验证会话

Session Refresh Flow

会话刷新流程

  1. User navigates to any route
  2. Middleware runs and refreshes session if needed
  3. Updated session cookie sent to client
  4. Server Components have access to fresh session
  1. 用户导航至任意路由
  2. 中间件运行并在需要时刷新会话
  3. 更新后的会话Cookie发送至客户端
  4. 服务端组件可获取最新会话

Logout Flow

登出流程

  1. User clicks logout button
  2. Server Action calls Supabase
    signOut()
  3. Session and cookies cleared
  4. User redirected to home page
  1. 用户点击登出按钮
  2. 服务端操作调用Supabase
    signOut()
  3. 会话和Cookie被清除
  4. 用户被重定向至首页

Route Protection Patterns

路由保护模式

Protecting Individual Pages

保护单个页面

Use
requireAuth()
at the top of Server Components:
typescript
import { requireAuth } from '@/lib/auth/utils';

export default async function ProtectedPage() {
  const user = await requireAuth();

  return <div>Hello {user.email}</div>;
}
在服务端组件顶部使用
requireAuth()
typescript
import { requireAuth } from '@/lib/auth/utils';

export default async function ProtectedPage() {
  const user = await requireAuth();

  return <div>你好,{user.email}</div>;
}

Protecting Route Groups

保护路由组

Use Next.js route groups with layout:
typescript
// app/(protected)/layout.tsx
import { requireAuth } from '@/lib/auth/utils';

export default async function ProtectedLayout({ children }) {
  await requireAuth();
  return <>{children}</>;
}
All routes in
(protected)
group are automatically protected.
使用Next.js路由组和布局:
typescript
// app/(protected)/layout.tsx
import { requireAuth } from '@/lib/auth/utils';

export default async function ProtectedLayout({ children }) {
  await requireAuth();
  return <>{children}</>;
}
(protected)
组内的所有路由会被自动保护。

Optional Authentication

可选认证

Check if user is logged in without requiring it:
typescript
import { getCurrentUser } from '@/lib/auth/utils';

export default async function OptionalAuthPage() {
  const user = await getCurrentUser();

  return (
    <div>
      {user ? `Welcome ${user.email}` : 'Please log in'}
    </div>
  );
}
检查用户是否登录但不强制要求:
typescript
import { getCurrentUser } from '@/lib/auth/utils';

export default async function OptionalAuthPage() {
  const user = await getCurrentUser();

  return (
    <div>
      {user ? `欢迎,${user.email}` : '请登录'}
    </div>
  );
}

Server Actions with Authentication

带认证的服务端操作

Protect Server Actions using
requireAuth()
:
typescript
'use server';

import { requireAuth } from '@/lib/auth/utils';
import { createServerClient } from '@/lib/supabase/server';

export async function updateProfile(formData: FormData) {
  const user = await requireAuth();
  const supabase = createServerClient();

  const { error } = await supabase
    .from('profiles')
    .update({ name: formData.get('name') })
    .eq('id', user.id);

  if (error) throw error;
}
使用
requireAuth()
保护服务端操作:
typescript
'use server';

import { requireAuth } from '@/lib/auth/utils';
import { createServerClient } from '@/lib/supabase/server';

export async function updateProfile(formData: FormData) {
  const user = await requireAuth();
  const supabase = createServerClient();

  const { error } = await supabase
    .from('profiles')
    .update({ name: formData.get('name') })
    .eq('id', user.id);

  if (error) throw error;
}

Troubleshooting

故障排除

Session not persisting: Verify cookies are being set. Check browser dev tools > Application > Cookies. Ensure domain matches.
Middleware redirect loop: Check matcher pattern doesn't include login page. Verify
/login
is accessible without auth.
OAuth redirect fails: Confirm callback URL matches exactly in Supabase dashboard. Check for trailing slashes.
TypeScript errors: Install types:
npm install -D @types/node
. Ensure
supabase
is typed correctly.
401 errors on protected routes: Session may be expired. Check Supabase dashboard > Authentication > Settings for session timeout.
会话不持久:验证Cookie是否已设置。查看浏览器开发者工具 > 应用 > Cookie,确保域名匹配。
中间件重定向循环:检查匹配规则是否包含登录页。确保
/login
无需认证即可访问。
OAuth重定向失败:确认回调URL与Supabase控制台中的设置完全一致,注意避免末尾斜杠。
TypeScript错误:安装类型定义:
npm install -D @types/node
。确保
supabase
的类型配置正确。
受保护路由返回401错误:会话可能已过期。查看Supabase控制台 > 认证 > 设置中的会话超时时间。

Resources

资源

scripts/

scripts/

No executable scripts needed for this skill.
本技能无需可执行脚本。

references/

references/

  • authentication-patterns.md
    - Common auth patterns and best practices for Next.js + Supabase
  • security-considerations.md
    - Security best practices for session handling and cookie configuration
  • authentication-patterns.md
    - Next.js + Supabase的通用认证模式与最佳实践
  • security-considerations.md
    - 会话处理与Cookie配置的安全最佳实践

assets/

assets/

  • supabase-client.ts
    - Browser-side Supabase client configuration
  • supabase-server.ts
    - Server-side Supabase client for Server Components
  • supabase-middleware.ts
    - Middleware Supabase client for session refresh
  • middleware.ts
    - Next.js middleware for route protection
  • auth-utils.ts
    - Helper functions for authentication checks
  • auth-actions.ts
    - Server Actions for logout and other auth operations
  • login-page.tsx
    - Complete login page with email/password and OAuth
  • dashboard-page.tsx
    - Example protected page using requireAuth
  • auth-callback-route.ts
    - OAuth callback handler for provider authentication
  • supabase-client.ts
    - 浏览器端Supabase客户端配置
  • supabase-server.ts
    - 服务端组件专用的服务端Supabase客户端
  • supabase-middleware.ts
    - 用于会话刷新的中间件Supabase客户端
  • middleware.ts
    - 用于路由保护的Next.js中间件
  • auth-utils.ts
    - 认证检查的辅助函数
  • auth-actions.ts
    - 登出及其他认证操作的服务端操作
  • login-page.tsx
    - 包含邮箱/密码和OAuth的完整登录页
  • dashboard-page.tsx
    - 使用requireAuth的受保护页面示例
  • auth-callback-route.ts
    - 提供商认证的OAuth回调处理器