文章目录
-
-
- 一、前期准备:账号注册与项目初始化
-
- [1.1 注册 Supabase 账号](#1.1 注册 Supabase 账号)
- [1.2 创建首个 Supabase 项目](#1.2 创建首个 Supabase 项目)
- [1.3 获取核心访问凭证](#1.3 获取核心访问凭证)
- 二、核心功能实战:从配置到开发
-
- [2.1 数据库配置:创建表与安全策略](#2.1 数据库配置:创建表与安全策略)
- [2.2 认证系统:实现登录注册功能](#2.2 认证系统:实现登录注册功能)
-
- [方式 1:邮箱 / 密码认证(基础版)](#方式 1:邮箱 / 密码认证(基础版))
- [方式 2:GitHub OAuth 登录(快捷版)](#方式 2:GitHub OAuth 登录(快捷版))
- [2.3 存储服务:文件上传与访问控制](#2.3 存储服务:文件上传与访问控制)
- [2.4 实时数据:实现文件列表自动更新](#2.4 实时数据:实现文件列表自动更新)
- [2.5 边缘函数:文件上传后发送通知](#2.5 边缘函数:文件上传后发送通知)
- 三、进阶操作:优化与扩展
-
- [3.1 开发环境隔离:使用分支功能](#3.1 开发环境隔离:使用分支功能)
- [3.2 性能优化技巧](#3.2 性能优化技巧)
- [3.3 安全加固措施](#3.3 安全加固措施)
- 四、常见问题与排查
-
- [4.1 数据无法访问?检查 RLS 策略](#4.1 数据无法访问?检查 RLS 策略)
- [4.2 实时订阅无响应?检查通道状态](#4.2 实时订阅无响应?检查通道状态)
- [4.3 文件上传失败?检查存储权限](#4.3 文件上传失败?检查存储权限)
-
一、前期准备:账号注册与项目初始化
1.1 注册 Supabase 账号
Supabase 支持多种快捷登录方式,推荐使用 GitHub 账号登录(适配开源开发者习惯):
-
选择 "Continue with GitHub",授权 GitHub 账号完成登录
-
首次登录需完善基本信息(姓名、邮箱),无需信用卡即可使用免费计划
1.2 创建首个 Supabase 项目
-
登录后进入控制台,点击 "New Project" 按钮
-
填写项目核心信息:
-
Project Name:如 "file-management-system"(建议与实战项目匹配)
-
Password:设置数据库管理员密码(需牢记,自托管时会用到)
-
Region:选择就近区域(如亚洲用户选 "Singapore",降低延迟)
-
Pricing Plan:默认选择 "Free"(包含 500MB 存储、1GB 数据库,足够原型开发)
- 点击 "Create Project",等待 2-3 分钟完成初始化(后台自动部署 Postgres 与配套服务)
1.3 获取核心访问凭证
项目创建后,进入 "Settings"→"API" 页面,记录三个关键信息(前端开发必备):
-
Project URL :API 访问基础地址(如
https://abc123.supabase.co) -
anon public:匿名访问密钥(前端 SDK 初始化用,默认带有限制权限)
-
service_role:管理员密钥(后端 / 函数用,需严格保密,勿暴露在前端)
二、核心功能实战:从配置到开发
以 "文件管理系统" 实战场景为例,详解 Supabase 五大核心功能的使用流程:
2.1 数据库配置:创建表与安全策略
通过 Supabase Studio 可视化操作,无需手写 SQL 即可完成数据层搭建:
- 进入 "SQL Editor"→"New Query",使用 AI 助手生成建表语句:
-
输入自然语言:"创建用户文件表,包含 id、user_id、file_name、file_path、size、created_at 字段"
-
点击 "Generate SQL",系统自动生成建表语句,点击 "Run" 执行
- 配置 行级安全(RLS)(实现 "用户仅访问自己的文件"):
-
进入 "Authentication"→"Policies",点击 "New Policy"
-
选择 "For full access"→"Use template",设置规则:
-
表:
user_files -
权限:
SELECT/INSERT/UPDATE/DELETE -
条件:
user_id = auth.uid()(自动关联当前登录用户 ID)
-
- 验证配置:进入 "Table Editor",手动插入测试数据(指定
user_id为某个用户 UUID),切换用户登录后仅能看到自己的数据
2.2 认证系统:实现登录注册功能
基于 JS SDK 快速集成认证模块,支持邮箱 / 密码与 OAuth 两种方式:
方式 1:邮箱 / 密码认证(基础版)
// 1. 初始化客户端(全局仅需执行一次)
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
import.meta.env.VITE_SUPABASE_URL, // 从环境变量读取,避免硬编码
import.meta.env.VITE_SUPABASE_ANON_KEY
)
// 2. 用户注册
const signUp = async (email, password) => {
const { data, error } = await supabase.auth.signUp({
email,
password,
options: {
data: { // 额外存储用户昵称等信息
username: 'new-user'
}
}
})
if (error) throw error
return data.user // 返回新创建的用户对象
}
// 3. 用户登录
const signIn = async (email, password) => {
const { data, error } = await supabase.auth.signInWithPassword({
email,
password
})
if (error) throw error
return data.session // 返回包含 JWT 的会话信息
}
// 4. 监听登录状态变化
supabase.auth.onAuthStateChange((event, session) => {
if (event === 'SIGNED_IN') {
console.log('用户已登录:', session.user.id)
// 跳转到文件列表页
} else if (event === 'SIGNED_OUT') {
// 清空本地缓存,跳转到登录页
}
})
方式 2:GitHub OAuth 登录(快捷版)
const signInWithGitHub = async () => {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'github',
options: {
redirectTo: 'http://localhost:3000/callback' // 登录成功后的回调地址
}
})
if (error) throw error
// 自动跳转至 GitHub 授权页面
}
2.3 存储服务:文件上传与访问控制
基于 S3 兼容的存储服务,实现文件的安全管理:
- 先在 Supabase 控制台创建存储桶:
-
进入 "Storage"→"New Bucket",名称设为 "user-documents"
-
权限选择 "Private"(仅认证用户可访问)
-
勾选 "Enable Row Level Security"(与 RLS 联动)
-
前端实现文件上传与下载:
// 1. 上传文件(需用户已登录)
const uploadFile = async (file) => {
// 生成唯一文件名,避免重复 const fileName = ${Date.now()}-${file.name}` // 上传路径格式:桶名/用户ID/文件名 const filePath = `user-documents/${supabase.auth.user().id}/${fileName}` const { data, error } = await supabase.storage .from('user-documents') .upload(filePath, file, { cacheControl: '3600', // 缓存1小时 upsert: false // 不允许覆盖同名文件 }) if (error) throw error // 上传成功后,将文件信息存入数据库 await supabase .from('user_files') .insert({ user_id: supabase.auth.user().id, file_name: file.name, file_path: data.path, size: file.size }) return data}
// 2. 获取文件访问链接(临时签名URL)
const getFileUrl = async (filePath) => {
const { data, error } = await supabase.storage .from('user-documents') .createSignedUrl(filePath, 3600) // 1小时有效期 if (error) throw error return data.signedUrl // 用于下载或预览文件}
2.4 实时数据:实现文件列表自动更新
借助 WebSocket 服务,无需刷新页面即可同步数据变化:
// 订阅当前用户的文件变更
const subscribeToFiles = () => {
const user = supabase.auth.user()
if (!user) return
// 创建订阅通道(命名为"user-files"便于管理)
const channel = supabase.channel('user-files')
// 监听 user_files 表的 INSERT/UPDATE/DELETE 事件
channel.on(
'postgres_changes',
{
event: '*', // 监听所有事件
schema: 'public',
table: 'user_files',
filter: `user_id=eq.${user.id}` // 仅订阅当前用户的数据
},
(payload) => {
// 根据事件类型更新前端列表
switch (payload.eventType) {
case 'INSERT':
addFileToUI(payload.new) // 添加新文件
break
case 'DELETE':
removeFileFromUI(payload.old.id) // 删除文件
break
case 'UPDATE':
updateFileInUI(payload.new) // 更新文件信息
break
}
}
).subscribe() // 启动订阅
// 组件卸载时取消订阅
return () => supabase.removeChannel(channel)
}
2.5 边缘函数:文件上传后发送通知
创建边缘函数处理异步逻辑,避免前端直接处理复杂业务:
-
安装 Supabase CLI(需先安装 Node.js):
npm install -g supabase
-
初始化函数项目并创建函数:
supabase init # 初始化本地配置
supabase functions new file-upload-notification # 创建函数
-
编写函数逻辑(
supabase/functions/file-upload-notification/index.ts):import { createClient } from '@supabase/supabase-js'
// 使用 service_role 密钥初始化(拥有管理员权限)
const supabase = createClient(
Deno.env.get('SUPABASE_URL')!, Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!)
Deno.serve(async (req) => {
const { filePath, userId } = await req.json() // 1. 获取用户邮箱 const { data: user } = await supabase .from('profiles') .select('email') .eq('id', userId) .single() // 2. 发送通知(此处简化为日志,实际可集成邮件服务) console.log(`通知用户 ${user.email}:文件 ${filePath} 已上传`) return new Response(JSON.stringify({ status: 'success' }), { status: 200 })})
-
部署函数并配置触发:
supabase functions deploy file-upload-notification # 部署到边缘节点
-
在控制台进入 "Edge Functions"→"Triggers",添加存储事件触发:
-
触发源:
storage.objects.insert(文件上传时触发) -
目标函数:
file-upload-notification
-
三、进阶操作:优化与扩展
3.1 开发环境隔离:使用分支功能
类似 Git 分支,创建独立开发环境避免影响生产数据:
-
进入项目控制台→"Project Settings"→"Branches"
-
点击 "Create Branch",命名为 "dev"
-
开发环境使用分支的 URL 与密钥,测试完成后通过 "Merge" 合并到主分支
3.2 性能优化技巧
-
数据库索引 :在
user_files.user_id和user_files.created_at字段创建索引,加速查询 -
API 缓存 :对静态数据(如文件分类)启用缓存,设置
cacheControl: 'public, max-age=86400' -
批量操作 :使用
insert([...items])替代循环单个插入,减少 API 调用次数
3.3 安全加固措施
-
密钥管理 :前端仅使用
anon public密钥,service_role仅在边缘函数或后端使用 -
存储策略 :为存储桶添加访问策略,限制用户仅能访问自己路径下的文件(
storage.foldername() = auth.uid()) -
SQL 防护 :禁用公共 schema 的
ALTER TABLE权限,防止恶意修改表结构
四、常见问题与排查
4.1 数据无法访问?检查 RLS 策略
-
现象:调用
select接口返回空数组,但表中存在数据 -
排查:进入 "Table Editor"→"Policies",确认策略是否生效,可临时关闭 RLS 测试(生产环境禁用此操作)
4.2 实时订阅无响应?检查通道状态
-
现象:数据变更后前端未收到通知
-
排查:
-
确认用户已登录(匿名用户可能无订阅权限)
-
检查过滤条件是否正确(如
user_id拼写错误) -
调用
channel.getStatus()查看订阅状态是否为 "SUBSCRIBED"
4.3 文件上传失败?检查存储权限
-
现象:上传返回 "403 Forbidden"
-
排查:
-
确认存储桶权限为 "Private" 而非 "Public"
-
检查上传路径是否符合策略要求(如是否包含用户 ID)
-
查看控制台 "Storage"→"Logs" 获取详细错误信息