You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Supabase实时RLS配置:基于唯一URL限制数据删改权限

实现无登录下基于唯一链接的Supabase行权限控制

核心思路

借助Supabase的行级安全(RLS)+ 会话变量传递edit_link参数,同时确保实时订阅也严格遵循权限规则。

步骤1:开启表的RLS

先给boards表启用行级安全,禁用默认的全表访问权限:

ALTER TABLE boards ENABLE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS "Allow all access to boards" ON boards;

步骤2:创建会话变量与RLS策略

注册一个自定义会话变量,再编写针对匿名用户的更新、删除策略,仅允许操作edit_link匹配会话变量的行:

-- 注册自定义会话变量(仅需执行一次)
ALTER ROLE anon SET app.current_edit_link = '';

-- 创建更新策略:限制仅能修改匹配edit_link的行,且不允许修改edit_link本身
CREATE POLICY "Allow update only for matching edit_link" ON boards
FOR UPDATE TO anon
USING (edit_link = current_setting('app.current_edit_link', true)::text)
WITH CHECK (edit_link = current_setting('app.current_edit_link', true)::text);

-- 创建删除策略:仅能删除匹配edit_link的行
CREATE POLICY "Allow delete only for matching edit_link" ON boards
FOR DELETE TO anon
USING (edit_link = current_setting('app.current_edit_link', true)::text);

USING控制哪些行可被选中操作,WITH CHECK确保更新后的数据仍符合权限规则,防止用户篡改edit_link。

步骤3:客户端传递edit_link参数

在用户访问/edit/xyz页面时,先通过RPC调用设置会话变量,后续所有操作(更新、删除、实时订阅)都会自动遵守RLS规则:

// 客户端JS代码示例
const editLink = window.location.pathname.split('/')[2]; // 从URL中提取xyz

// 先调用RPC设置会话变量
await supabase.rpc('set_current_edit_link', { link: editLink });

// 执行更新操作(eq条件可省略,RLS会自动过滤)
await supabase
  .from('boards')
  .update({ title: '更新后的标题' })
  .eq('edit_link', editLink);

// 实时订阅:仅会收到匹配当前edit_link的行变更
const subscription = supabase
  .channel('board_updates')
  .on('postgres_changes', 
    { event: '*', schema: 'public', table: 'boards' }, 
    (payload) => console.log('行变更:', payload)
  )
  .subscribe();

对应的RPC函数需提前创建:

CREATE OR REPLACE FUNCTION set_current_edit_link(link text)
RETURNS void AS $$
BEGIN
  PERFORM set_config('app.current_edit_link', link, true);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- 给匿名用户授予执行该函数的权限
GRANT EXECUTE ON FUNCTION set_current_edit_link(text) TO anon;

SECURITY DEFINER确保匿名用户能通过函数修改会话变量(匿名用户本身无直接调用set_config的权限)。

实时场景注意事项

  • 订阅会自动应用RLS策略,只要提前设置好会话变量,只会收到符合当前edit_link的行变更。
  • 页面刷新后需重新调用RPC设置会话变量,因为会话变量绑定在当前连接上。

额外安全加固

  • 确保edit_link是足够随机的长字符串(比如用gen_random_uuid()生成),避免被暴力猜解。
  • 给boards表的edit_link列添加唯一约束,防止重复:
ALTER TABLE boards ADD CONSTRAINT unique_edit_link UNIQUE (edit_link);

内容的提问来源于stack exchange,提问作者AndersD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:30:09