初探supabase: RLS、trigger、edge function

supabase是什么?

一个BaaS,在postgres上增加api层,为每个表生成api。并且支持 edge function(serverless函数调用),storage (对象存储),认证等

管理项目

创建一个Project,填写基本信息,包括数据库密码,选择Region

创建好之后,到首页可以看到一个URL和API KEY,前端将通过他来调用 supabase的提供的data api对数据库进行增删改查。

下面的小字说,这个key是可以被公开的,那么supabase是如何确保数据库操作的安全呢?答案是通过RLS实现的行级别的鉴权,这个后面会说到。

认证

supabase提供了开箱即用的认证功能,可以不写一行代码实现用户注册、登录等。

到 API docs -- User Managerment可以看到如何用去注册一个用户

我们命令行复制 并执行:

发现api成功返回了,然后到Table Editor中auth.users中可以看到,多了一条用户记录

这里schema有多种,其中auth是supabase直接管理的,用来实现认证,用户不能进行修改

用户创建的表在public下,创建完之后 supabase 会自动生成增删改查的api

建表

从上一部分可以看到,auth.users 并不存在 用户名称、简介等业务信息,就需要我们自己在public下创建一个users表,然后使用外键建立关联

设置外键,将public.users.uid 指向 auth.users.id ,并且设置当 auth.users记录被删除时,同步删除业务表的记录

trigger function

现在发现了个问题,当用户注册的时候,auth.users 会多一条记录,但是public.users却没有,难道还需要我们登录之后手动调用insert创建吗?

其实不用,我们可以使用supabase的trigger function,auth.users改变时触发,执行sql给public.users插入一条记录

到 Database -> function, 在public创建一个function,其实就是执行了一段sql,其中 new 代表auth.users中的一条记录,raw_user_meta_data 则是调用接口时传入的业务对象,这个现在看起来有点懵逼,后面会说到

sql 复制代码
-- 创建函数
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO public.users (uid, username)
  VALUES (
    NEW.id,
    NEW.raw_user_meta_data->>'username',
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

有了执行逻辑,还要定义什么时候触发,到database -> triggers, 在public下新增一个trigger,指定到auth.users表插入的时候执行对应的trigger:

sql 复制代码
-- 创建触发器
CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();

然后删除刚刚的数据,

sql 复制代码
delete from auth.users where id = '06ca9840-a63f-447e-96af-e7f3ff768342'

重新注册一下,注意这里data对象就是上面函数中的raw_user_meta_data:

再查看一下业务表 public.users,多了一条记录

RLS: Row Level Security

如果想对某些行进行鉴权,比如

  1. 用户只能修改自己的信息
  2. 任何人都可以创建post
  3. 任何人只能查看自己的post

就需要用到RLS,通过创建polices来控制,官方的例子很具体了,这里解释一下

vbnet 复制代码
create policy "Public profiles are viewable only by authenticated users"
on profiles for select
to authenticated
using ( true );

表示创建了一个规则,对于profiles的select操作,对登录用户进行限制,限制为true,就是任何登录用户都可以查看profiles

sql 复制代码
create policy "Users can update their own profile."
on profiles for update
to authenticated -- the Postgres Role (recommended)
using ( (select auth.uid()) = user_id ) -- checks if the existing row complies with the policy expression
with check ( (select auth.uid()) = user_id ); -- checks if the new row complies with the policy expression

这里 auth.uid() 是从读取请求中的jwt解析得到的人当前登录用户的id,user_id是表中的列

这个polices限制了,对于profile的更新操作,只有登录用户,可以查看到自己的(using),并且修改后id不能变(with check),没有with check的话,用户可以把自己的profile中的uid改成别人的

这里区分一下using和with check的区别:

逻辑 含义
USING 能不能选中这行(决定可操作范围)
WITH CHECK 改完后是否合法(防止越权写入)

待补充

相关推荐
崔庆才丨静觅1 天前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 天前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 天前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 天前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 天前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅1 天前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment1 天前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅1 天前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊1 天前
jwt介绍
前端
爱敲代码的小鱼1 天前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax