用途
Supabase 是一个开源 Firebase 替代方案,提供专用 PostgreSQL 数据库,并打包了身份认证(Auth)、实时订阅(Realtime)、存储(Storage)和 Edge Functions。该技能适用于构建全栈 Web/移动应用时获取 Supabase 相关协助,覆盖 PostgreSQL、行级安全(RLS)、Edge Functions、Auth 与 pgvector 等主题。
主要能力
- 开源 Firebase 替代方案:完整的后端即服务,提供 PostgreSQL、Auth、Realtime、Storage 和 Edge Functions。
- 完整的关系型 PostgreSQL 能力:直接访问真实的 PostgreSQL,支持扩展(pgvector、PostGIS、pg_cron),无专有厂商锁定。
- 行级安全(RLS)授权:通过 SQL 安全策略在数据库层直接保护多租户客户端查询。
- 实时数据库订阅:从客户端应用通过 WebSocket 订阅 PostgreSQL 的插入、更新和删除事件。
使用方式
快速开始示例(JavaScript/TypeScript 客户端):
import { createClient } from "@supabase/supabase-js";
const supabase = createClient("https://xyz.supabase.co", "public-anon-key");
// Listen to changes
const subscription = supabase
.channel("public:messages")
.on(
"postgres_changes",
{ event: "INSERT", schema: "public", table: "messages" },
(payload) => {
console.log("New message:", payload);
},
)
.subscribe();
PostgreSQL 行级安全(RLS)
在数据库层保护数据,使客户端可以安全地直接从 Web/移动应用查询数据库:
-- Enable RLS on Table
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
-- Allow users to read and update only documents they own
CREATE POLICY "Users access own documents"
ON documents
FOR ALL
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
现代 Supabase JavaScript / TypeScript 客户端
类型安全的数据库查询、身份认证和文件存储:
import { createClient } from "@supabase/supabase-js";
import { Database } from "./types/supabase";
const supabase = createClient<Database>(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!,
);
// Query with automated RLS enforcement
const { data: projects, error } = await supabase
.from("projects")
.select("id, title, tasks(id, name, status)")
.eq("status", "active")
.order("created_at", { ascending: false });
实时 WebSocket 广播与在线状态
流式传输实时变更并同步用户在线状态:
// Subscribe to real-time database changes on orders table
const channel = supabase
.channel("db-changes")
.on(
"postgres_changes",
{ event: "INSERT", schema: "public", table: "orders" },
(payload) => {
console.log("New Order Created:", payload.new);
},
)
.subscribe();
常见模式:多租户隔离的 RLS 策略
问题:当客户端查询缺少手动租户过滤时,API 可能意外泄露私有用户记录。
解决方案:使用 auth.uid() 在数据库层强制执行行级安全:
-- Enable RLS
ALTER TABLE user_notes ENABLE ROW LEVEL SECURITY;
-- Restrict reads and writes exclusively to the owning user
CREATE POLICY "Users can only access own notes"
ON user_notes
FOR ALL
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
最佳实践
建议做:
- 始终启用行级安全(RLS):在未启用并测试 RLS 策略前,绝不要将表暴露给公共 API。
- 生成严格的 TypeScript 类型:使用 Supabase CLI(supabase gen types typescript)保持数据库模式强类型。
- 为 RLS 策略中使用的列建立索引:在 user_id 或 organization_id 上添加索引,避免策略评估时出现慢表扫描。
- 对敏感逻辑使用 Edge Functions:将私有 API 密钥和支付集成保留在服务端 Edge Functions 中。
不建议做:
- 在客户端代码中暴露 service_role 密钥:service_role 密钥会绕过所有 RLS 策略,必须严格保存在安全服务器上。
- 在 RLS 策略中编写复杂的嵌套子查询:缓慢的 RLS 子查询会在每次逐行检查时成倍增加延迟。
- 跳过 Git 中的数据库迁移:使用 supabase migration new 并对所有数据库 DDL 变更进行版本控制。
故障排查
| 错误 | 原因 | 解决方案 |
|---|---|---|
| SELECT 查询返回空数组 [] | 表已启用 RLS,但没有策略匹配当前已认证用户。 | 创建适当的 RLS 策略,或验证客户端 JWT 令牌包含有效的用户会话。 |
| JWT 过期 / 无效刷新令牌 | 用户会话令牌过期且未刷新。 | 调用 supabase.auth.refreshSession() 或处理认证状态变更监听器。 |
| 数据库连接数超限 | 无服务器边缘函数超出直接 Postgres 连接数。 | 通过 PgBouncer 使用 Supabase 连接池(端口 6543)。 |
适用场景
- 构建全栈 Web/移动应用,需要 PostgreSQL、Auth、Realtime、Storage 和 Edge Functions 的一体化后端。
- 需要多租户数据隔离,并希望在数据库层通过 RLS 策略保证安全。
- 需要实时订阅数据库变更并同步用户在线状态的应用。
- 需要类型安全的数据库查询与文件存储的 JavaScript/TypeScript 项目。
限制
资料未提供关于收费、价格、平台支持范围、性能指标或具体使用步骤的更多信息,相关内容暂未提供。