Supabase(https://supabase.com/)是一个开源的Baas平台(BaaS, Backend as a Service,后端即服务)。本文演示Supabase的使用流程。
**目标:**通过一个最基础的 Web 项目,熟悉Supabase 入门使用流程,让项目"能跑起来"。
这里使用比较常见的组合:Supabase + Next.js / React 的思路。
1. Supabase流程概览
Supabase 入门的核心就是:创建项目 → 建表 → 配置 RLS → 前端接入 SDK → 做认证 → 做 CRUD。
在 Supabase 控制台里创建一个项目后,就会得到:
- 一个 PostgreSQL 数据库
- 一个项目 URL
- 一个匿名公钥(anon key)
- 用户认证服务
- 文件存储
- 实时功能
- 可选的 Edge Functions
前端通过 Supabase SDK 连接它,就能:
- 注册/登录用户
- 查询数据库
- 插入数据
- 上传文件
- 订阅实时更新
2. 准备工作
使用Supabase之前,需要准备:
- 一个 Supabase 账号(https://supabase.com/)
- Node.js 环境
- 一个前端项目(React / Next.js / Vue 都行)
当然,如果只是想体验Supabase,也可以先只在 Supabase 控制台里操作数据库,不写代码。
3. Supabase使用流程演示
3.1 Supabase部分
step1. 创建 Supabase 项目
1. 注册并登录: 去 Supabase 官网(https://supabase.com/)创建账号并登录。
**2. 创建一个新项目:**进入 dashboard 后
- 点击 New Project
- 选择组织
- 输入项目名称
- 输入数据库密码
- 选择地区
- 创建项目
创建完成后,Supabase 会帮你初始化 Postgres、Auth 等服务。
step2. 拿到项目连接信息
创建好项目后,去项目设置里找到:
- Project URL
- API Key
anon publickeyservice_rolekey
入门阶段主要先用:
SUPABASE_URL -->Project URLSUPABASE_ANON_KEY --> anon publickey
注意:
- anon key 可以在前端使用
- service_role key 绝对不要暴露到前端
step3. 创建一张测试表
我们先创建一个最简单的 todos 表。进入 Supabase 的 SQL Editor,执行下面 SQL:
sql
create table todos (
id bigint generated by default as identity primary key,
created_at timestamp with time zone default timezone('utc'::text, now()) not null,
title text not null,
is_done boolean default false,
user_id uuid references auth.users(id)
);
这张表表示:
id:主键created_at:创建时间title:待办标题is_done:是否完成user_id:属于哪个用户
step4. 开启行级安全(RLS)
Supabase 非常强调安全,建议从入门开始就养成配置 RLS(Row Level Security,行级安全)的习惯。
执行:
sql
alter table todos enable row level security;
这样默认情况下,前端将不能随便读写这张表,除非你写 policy。
step5. 添加安全策略(Policy)
我们希望做到:
- 用户只能看自己的 todos
- 用户只能插入自己的 todos
- 用户只能修改自己的 todos
- 用户只能删除自己的 todos
执行下面 SQL:
sql
-- 1. 允许查询自己的数据
create policy "Users can view their own todos"
on todos
for select
using (auth.uid() = user_id);
-- 2. 允许插入自己的数据
create policy "Users can insert their own todos"
on todos
for insert
with check (auth.uid() = user_id);
-- 3. 允许更新自己的数据
create policy "Users can update their own todos"
on todos
for update
using (auth.uid() = user_id);
-- 4. 允许删除自己的数据
create policy "Users can delete their own todos"
on todos
for delete
using (auth.uid() = user_id);
这一步非常关键。没有 policy,你前端即使连上了 Supabase,也可能查不到数据。
3.2 前端部分
step1. 创建前端项目
如果你想快速开始,可以用 Next.js:
bash
npx create-next-app@latest my-supabase-app
cd my-supabase-app
npm install @supabase/supabase-js
如果你是普通 React 项目,也一样安装:
bash
npm install @supabase/supabase-js
step2. 初始化 Supabase 客户端
在项目中创建一个文件,比如:
javascript
// lib/supabase.js
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
然后在 .env.local 中写入:
bash
NEXT_PUBLIC_SUPABASE_URL=你的项目URL
NEXT_PUBLIC_SUPABASE_ANON_KEY=你的anon key
注意:
- 在 Next.js 里,前端可读取的环境变量通常要以
NEXT_PUBLIC_开头。
step3. 用户注册/登录
Supabase Auth 的基础使用非常简单。
1. 邮箱注册
javascript
const signUp = async () => {
const { data, error } = await supabase.auth.signUp({
email: 'test@example.com',
password: '12345678',
})
if (error) {
console.error('注册失败:', error.message)
} else {
console.log('注册成功:', data)
}
}
2. 邮箱登录
javascript
const signIn = async () => {
const { data, error } = await supabase.auth.signInWithPassword({
email: 'test@example.com',
password: '12345678',
})
if (error) {
console.error('登录失败:', error.message)
} else {
console.log('登录成功:', data)
}
}
3. 获取当前用户
javascript
const getUser = async () => {
const { data, error } = await supabase.auth.getUser()
if (error) {
console.error(error.message)
} else {
console.log(data.user)
}
}
4. 退出登录
javascript
const signOut = async () => {
const { error } = await supabase.auth.signOut()
if (error) {
console.error('退出失败:', error.message)
}
}
step4. 插入一条数据
用户登录后,插入 todo:
javascript
const addTodo = async () => {
const {
data: { user },
} = await supabase.auth.getUser()
if (!user) {
console.log('请先登录')
return
}
const { data, error } = await supabase
.from('todos')
.insert([
{
title: '学习 Supabase',
user_id: user.id,
},
])
.select()
if (error) {
console.error('插入失败:', error.message)
} else {
console.log('插入成功:', data)
}
}
这里必须传 user_id: user.id,否则会触发你前面设置的 RLS policy 校验失败。
step5. 查询当前用户的 todos
javascript
const fetchTodos = async () => {
const { data, error } = await supabase
.from('todos')
.select('*')
.order('created_at', { ascending: false })
if (error) {
console.error('查询失败:', error.message)
} else {
console.log('todos:', data)
}
}
你会发现:即使代码里没有写 where user_id = ...,由于 RLS policy 生效,用户也只能查到自己的数据。
当然,你也可以自己加过滤条件:
javascript
const { data, error } = await supabase
.from('todos')
.select('*')
.eq('is_done', false)
step6. 更新一条 todo
javascript
const updateTodo = async (id) => {
const { data, error } = await supabase
.from('todos')
.update({ is_done: true })
.eq('id', id)
.select()
if (error) {
console.error('更新失败:', error.message)
} else {
console.log('更新成功:', data)
}
}
由于 RLS 限制,只有当前用户自己的 todo 才能更新成功。
step7. 删除一条 todo
javascript
const deleteTodo = async (id) => {
const { error } = await supabase
.from('todos')
.delete()
.eq('id', id)
if (error) {
console.error('删除失败:', error.message)
} else {
console.log('删除成功')
}
}
step8. 监听登录状态变化
很多项目里需要知道用户是否已登录,可以这样监听:
javascript
supabase.auth.onAuthStateChange((event, session) => {
console.log('auth event:', event)
console.log('session:', session)
})
常见事件有:
SIGNED_INSIGNED_OUTTOKEN_REFRESHED
step9. 最简单页面示例
下面是一个非常简化的 React 页面逻辑示例:
javascript
'use client'
import { useEffect, useState } from 'react'
import { supabase } from './lib/supabase'
export default function Home() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [title, setTitle] = useState('')
const [todos, setTodos] = useState([])
//邮箱注册
const signUp = async () => {
const { error } = await supabase.auth.signUp({
email,
password,
})
if (error) alert(error.message)
else alert('注册成功')
}
//邮箱登录
const signIn = async () => {
const { error } = await supabase.auth.signInWithPassword({
email,
password,
})
if (error) alert(error.message)
else {
alert('登录成功')
fetchTodos()
}
}
//查询当前用户的 todos
const fetchTodos = async () => {
const { data, error } = await supabase
.from('todos')
.select('*')
.order('created_at', { ascending: false })
if (error) alert(error.message)
else setTodos(data)
}
//插入一条数据
const addTodo = async () => {
const {
data: { user },
} = await supabase.auth.getUser()
if (!user) {
alert('请先登录')
return
}
const { error } = await supabase.from('todos').insert([
{
title,
user_id: user.id,
},
])
if (error) alert(error.message)
else {
setTitle('')
fetchTodos()
}
}
//useEffect
useEffect(() => {
fetchTodos()
}, [])
return (
<main style={{ padding: 20 }}>
<h1>Supabase 入门 Demo</h1>
<div>
<input
placeholder="邮箱"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
placeholder="密码"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button onClick={signUp}>注册</button>
<button onClick={signIn}>登录</button>
</div>
<hr />
<div>
<input
placeholder="新的 todo"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<button onClick={addTodo}>添加</button>
</div>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
{todo.title} - {todo.is_done ? '已完成' : '未完成'}
</li>
))}
</ul>
</main>
)
}
这个示例比较粗糙,但足以打通完整流程:
- 注册
- 登录
- 插入数据
- 查询数据
4. Supabase常见问题
Supabase 最常遇到的问题基本就这几个:
4.1 没开启 RLS 或 policy 没写对
表现:
- 查询为空
- 插入失败
- 提示权限问题
建议:
- 检查表是否
enable row level security - 检查 policy 中
auth.uid() = user_id是否正确 - 确认用户真的已经登录
4.2 前端没拿到登录态
表现:
getUser()返回空- 插入时
user_id没值
建议:
- 确认登录成功
- 检查 session 是否存在
- 页面刷新后重新获取用户信息
4.3 环境变量写错
表现:
- SDK 初始化失败
- 请求报错
- 连接不到项目
建议:
- 检查 URL
- 检查 anon key
- 重启开发服务器
4.4 service_role key 放到前端
这是严重安全问题。
前端只能用 anon key,不要把 service_role 暴露出去。
5. 进阶学习
推荐的Supabase学习顺序:
- 创建项目
- 建表
- 开启 RLS
- 写 policy
- 实现邮箱注册/登录
- 做一套 CRUD
- 做用户 profile 表
- 接入文件上传
- 接入实时订阅
- 最后再学 Edge Functions
当入门流程通过后,建议继续学下述这几个方向:
1. Auth 进阶
- 邮箱验证
- OAuth 登录(Google/GitHub)
- 重置密码
- 用户资料表设计
2. 数据库设计
- 外键
- 索引
- 视图
- 存储过程 / SQL function
3. RLS 深入
- 多角色权限
- 管理员权限
- 团队空间权限
- 公有/私有数据混合访问
4. Storage
- 上传头像
- 上传文章封面
- 私有文件访问
5. Edge Functions
- Webhook
- 服务端逻辑
- 调用第三方 API
- 支付回调
6. 相关文档
-
Baas(后端即服务)简介: https://blog.csdn.net/taotiezhengfeng/article/details/159115849
-
开源Baas平台 Supabase 简介:https://blog.csdn.net/taotiezhengfeng/article/details/159116106
-
开源Baas平台 Supabase 入门演示:https://blog.csdn.net/taotiezhengfeng/article/details/159116342