2.6.1 Supabase 服务概览
一句话破题
Supabase 把 PostgreSQL 数据库、用户认证、文件存储、实时订阅打包成一个开箱即用的 BaaS 平台——你只需要写前端代码,后端它全包了。
核心服务详解
1. Database:PostgreSQL 数据库
typescript
// 直接在客户端查询数据库
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
// 查询
const { data, error } = await supabase
.from('posts')
.select('*, author:users(*)')
.eq('status', 'published')
.order('created_at', { ascending: false })
// 插入
const { data, error } = await supabase
.from('posts')
.insert({ title: 'Hello', content: 'World' })
.select()特点:
- 完整的 PostgreSQL,支持所有 SQL 特性
- 内置 Row Level Security(行级安全)
- 自动生成 REST API 和 GraphQL API
- 可视化数据库管理界面
2. Auth:用户认证
typescript
// 邮箱密码登录
const { data, error } = await supabase.auth.signInWithPassword({
email: 'user@example.com',
password: 'password',
})
// OAuth 登录(Google/GitHub 等)
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
})
// 获取当前用户
const { data: { user } } = await supabase.auth.getUser()
// 登出
await supabase.auth.signOut()支持的认证方式:
- 邮箱密码
- Magic Link(邮件链接)
- OAuth(Google、GitHub、Twitter 等)
- 手机验证码
3. Storage:文件存储
typescript
// 上传文件
const { data, error } = await supabase.storage
.from('avatars')
.upload(`${userId}/avatar.png`, file)
// 获取公开 URL
const { data } = supabase.storage
.from('avatars')
.getPublicUrl(`${userId}/avatar.png`)
// 下载文件
const { data, error } = await supabase.storage
.from('documents')
.download('report.pdf')特点:
- 与 Auth 集成,支持权限控制
- 自动 CDN 加速
- 支持图片处理(缩放、裁剪)
4. Realtime:实时订阅
typescript
// 订阅数据变更
const channel = supabase
.channel('posts')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'posts' },
(payload) => {
console.log('变更:', payload)
}
)
.subscribe()
// 取消订阅
supabase.removeChannel(channel)适用场景:
- 实时聊天
- 协作编辑
- 实时通知
- 数据看板
行级安全(RLS)
Supabase 最强大的特性之一是 Row Level Security:
sql
-- 用户只能看到自己的文章
CREATE POLICY "用户只能查看自己的文章" ON posts
FOR SELECT
USING (auth.uid() = author_id);
-- 用户只能修改自己的文章
CREATE POLICY "用户只能修改自己的文章" ON posts
FOR UPDATE
USING (auth.uid() = author_id);
-- 任何人都可以查看已发布的文章
CREATE POLICY "公开文章所有人可见" ON posts
FOR SELECT
USING (status = 'published');与 Next.js 集成
安装
bash
pnpm add @supabase/supabase-js @supabase/ssr配置
typescript
// lib/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr'
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
}typescript
// lib/supabase/server.ts
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export function createClient() {
const cookieStore = cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
},
}
)
}在 Server Component 中使用
typescript
// app/posts/page.tsx
import { createClient } from '@/lib/supabase/server'
export default async function PostsPage() {
const supabase = createClient()
const { data: posts } = await supabase
.from('posts')
.select('*')
.eq('status', 'published')
return (
<ul>
{posts?.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}本节小结
| 服务 | 核心价值 | 注意事项 |
|---|---|---|
| Database | 完整 PostgreSQL + 自动 API | RLS 配置复杂 |
| Auth | 开箱即用的认证 | 定制化受限 |
| Storage | 与 Auth 集成的存储 | 大文件成本高 |
| Realtime | 零配置实时订阅 | 连接数有限制 |
