Topics

在业务应用中如何使用 Supabase 的 RLS

  • column

您好,我是 Liberogic 的 Matsun。

上一篇文章介绍了基于 Supabase Auth 与 Cloudflare 的带认证 Web 应用。本文是其延续,将深入讲解其中略有提及的 **RLS(Row Level Security,行级安全)**内容。

使用 Supabase Auth,可以

确认“当前登录的是谁”

,但在业务应用中,仅靠认证是不够的。

该用户可以查看哪些数据
可以修改哪些数据

都需要明确规定,而 RLS 正是用于实现这一点的机制。
本文将介绍在业务应用中如何使用 Supabase 的 RLS。

什么是 RLS

RLS 是 Row Level Security 的缩写,是一种以数据库“行”为单位控制访问权限的机制。
例如,假设申请数据中包含如下内容。

申請ID, 申請者, 所属会社, 所属拠点, 申請内容, ステータス

同一张表中包含所有用户的申请记录,

  • 普通员工登录时,希望只显示自己的申请。
  • 主管则希望能看到自己所在部门和据点的申请。
  • 总部管理员则希望能看到所有申请。

这种访问控制正是在数据库端实现的RLS,它是业务应用中的一项重要功能。

Auth与RLS职责不同

上一篇文章也提到过,Supabase Auth与RLS的职责各不相同。
按职责划分,两者的关系如下。

Supabase Auth → 誰なのか確認する
RLS → その人がどのデータにアクセスできるか決める

例如,森本先生登录系统后,通过Supabase Auth可以确认,

ユーザーID:12345

就是该用户。RLS则利用该用户ID,

申請者ID = 12345

只获取属于该用户的数据。
这样,即使同一张表中有1万条申请数据,森本先生也只能看到自己的申请。

最直观的是“只显示自己的数据”

在 RLS 中最容易想象的是 只显示用户自己数据 的模式。

例如,面向会员的个人主页中,

  • 自己的注册信息
  • 自己的申请记录
  • 自己的合同信息
  • 自己的咨询记录
  • 自己上传的文件

,仅予以显示。

应用程序端同样会指定用户 ID 来获取数据,但不能仅依赖于此,还需要在数据库端设定 **“仅限已登录本人的数据”** 这一规则。
在应用程序和数据库两侧进行控制非常重要。
即使前端页面实现有误,也可以通过 RLS 确保无法获取其他用户的数据。

按公司划分

在面向客户或合作伙伴的门户等场景中,通常不是按用户,而是按公司来展示数据。

例如,

A株式会社
 ├ 森本さん
 ├ 大塚さん
 └ 山田さん

例如,假设有3名用户,这3人都可以查看A株式会社的项目,但无法查看B株式会社的项目。在数据层面,则要建立如下关联:

ユーザー → 所属会社 → 案件

先建立这样的关联关系。
然后在 RLS 中设置,只允许用户访问其所属公司的数据。
这是客户门户中常见的架构,即使数十家、数百家公司使用同一个 Web 应用,登录的公司不同,可见的数据也会随之不同。

按据点划分

随着业务应用逐渐成型,除了公司之外,还会涉及据点。例如,

本部

東京支店
 ├ 担当者A
 └ 担当者B

大阪支店
 ├ 担当者C
 └ 担当者D

这样的结构。

  • 东京分店的负责人只能查看东京分店的数据。
  • 大阪分店的负责人只能查看大阪分店的数据。
  • 总部可以查看全部数据。

这是店铺管理、营业所管理、代理商管理等业务中很常见的结构。从这里开始,

ユーザー → 会社 → 拠点 → 役割 → アクセスできるデータ

就需要进行权限设计,在业务应用中,这种权限设计非常重要。

管理员可以查看全部数据

当然,也会有管理员这一角色。例如,

  • 普通用户
  • 据点管理员
  • 本部管理者
  • 系统管理员

这样来划分权限。

  • 普通用户只能查看自己的数据。
  • 网点管理员只能管理自己所在的网点。
  • 总部管理员可管理所有网点。
  • 系统管理员还可以进行用户管理等操作。

大致就是这样的结构。

一般ユーザー → 自分だけ
拠点管理者 → 所属拠点
本部管理者 → 全拠点

这些规则不仅放在应用端,也会放在 RLS 中。
仅隐藏管理界面的菜单并不能构成权限控制,因此需要确保无法直接访问数据本身。

不仅控制“能否查看”,还控制“能否修改”

RLS 并不只用于查看数据时。

以审批应用为例:

普通员工可以:

  • 创建自己的申请
  • 编辑自己的草稿
  • 已批准的申请不可修改

主管可以:

  • 查看下属的申请
  • 可进行审批和退回

总部管理员可以

  • 查看全部记录

等规则。也就是说,

見る・登録する・変更する・削除する

需要分别考虑这些情况,不能简单地只判断“这个人能否查看这些数据”,还需要把在业务上应如何处理这些数据也纳入权限设计之中。

不仅要设计查看权限,还需要设计新增、修改等操作权限。

不要只在应用端管理权限

例如在前端,

if 管理者 → 管理ボタンを表示

这样做本身很常见,但仅靠页面显示控制是不够的。

  • 即使浏览器中看不到按钮,如果有人直接调用 API,又该怎么处理?
  • 如果有人直接指定URL,该怎么办?
  • 如果有人指定其他用户ID来获取数据,该怎么办?

这类问题经常出现。因此实际上,

画面
↓
アプリケーション
↓
API
↓
RLS
↓
Database

需要在多个位置进行确认。
RLS的作用是在最底层、最接近数据库的位置保护数据。
在业务应用中,重要的不是“界面上看不到所以没问题”,而是从一开始就让数据无法被获取。

并不是只靠RLS就能解决所有问题

反过来,也没有必要只用RLS来实现所有的权限控制。

例如,

  • 是否应该打开这个页面
  • 是否应该执行这个API
  • 是否应该显示这个按钮
  • 在执行此处理之前,确认是否已获得批准

这些判断同样会在应用端进行。

在使用 Cloudflare Workers 的情况下,也可能由 Workers 端负责与外部 API 的通信以及服务端处理。
因此实际上,

Cloudflare
↓
Next.js
↓
Supabase Auth
↓
アプリケーション側の権限確認
↓
RLS
↓
Database

大致就是这样的思路。
与其试图在一个地方解决所有问题,不如在各个层级分别守住必要的环节。

管理类处理有时会绕过 RLS

这里稍微涉及一些技术内容。
在业务应用中,除了由用户本人操作的处理之外,还有由系统在后台运行的处理。

例如,

  • 面向管理员的批量处理
  • 批处理
  • 与外部系统的集成
  • 数据迁移
  • 管理用 API

等等。
在这类处理中,有时也需要在不受 RLS 约束的情况下处理数据。
Supabase 提供了供服务端管理处理使用的权限,但这些权限理所当然不应暴露到浏览器端。

ユーザーからの操作
↓
RLSを通す

管理・システム処理
↓
サーバー側で必要な権限を使う

按这样分开处理。
如果什么都用管理员权限来执行,那么设置 RLS 的意义也就荡然无存了。

在业务应用中,首先要制作权限表

在编写 RLS 之前,先梳理业务上的权限。
例如,对于审批类应用,大致是这样的。

                自分   拠点   全体   承認
一般ユーザー      ○     ×      ×      ×
上長              ○     ○      ×      ○
本部管理者        ○     ○      ○      ○

实际上会更加细致,

  • 查看
  • 注册
  • 更新
  • 删除
  • 批准
  • 输出

等类别。
确定这些之后,

どのテーブルに
どんな情報を持たせるか
↓
どのユーザーが
どの行にアクセスできるか
↓
RLSをどう設定するか

进行考虑。
在设置 RLS 之前,先梳理业务上的权限。
RLS 只是将业务上确定的权限落实到数据库中的一种机制。

权限设计尽早考虑会更省力

在开发业务应用时,经常会出现“先让所有人都能查看,之后再添加权限”的讨论。
如果只是小型原型,这样做也可以,但考虑到正式运营,尽早考虑权限设计会更省力。

之后再

  • 拆分公司
  • 拆分据点
  • 添加管理员
  • 添加代理商
  • 添加外部人员

则可能需要更改数据结构本身。
在 Supabase 中使用 RLS 时也是如此,

谁与谁在什么范围内共享数据

,如果事先考虑清楚,设计会清晰很多。

总结

使用 Supabase 的 RLS,可以将业务应用中所需的细粒度数据访问控制放在数据库端实现。

例如,

  • 可以只让用户看到自己的数据
  • 仅显示同一公司的数据
  • 只展示同一据点的数据
  • 管理员可查看全部数据
  • 仅特定人员可以更新

等控制。

Supabase Auth 负责确认“用户是谁”,RLS 则控制“该用户可以访问哪些数据”。

通过这种组合,可以实现业务应用所需的访问控制。
但真正重要的,并不是编写RLS本身。
首先,

明确谁可以在何处做什么

,即整理业务层面的权限范围。
这一点确定之后,Supabase Auth、应用端的权限控制以及RLS的角色设定也会自然而然地确定下来。

下一篇将讨论为什么要将Cloudflare Workers与Supabase结合使用。

撰写本文的人

平时虽然比较随性自在,但凡是让自己在意的事情,都会查到彻底弄明白为止。一边反复尝试、不断摸索,一边今天也静静地专注于开发工作。

Matsun

前端工程师

查看此员工的文章

以稳健的团队体制和迅速的应对能力为傲

Liberogic 的资深团队积极推动项目,因此深受客户好评。
我们致力于合理配置项目经理与总监,确保整个项目顺利推进。 我们采用按需投入的方式,避免不必要的全员投入导致成本增加,合理分配资源、人尽其才。同时,我们在掌握业务内容、制作与提交报价方面的速度也广受好评。

※ 当社不积极开展 SES 类驻场业务,敬请谅解。

您可以使用 Slack、Teams、Redmine、Backlog、Asana、Jira、Notion、Google Workspace、Zoom、Webex 等几乎所有主流的项目管理工具和聊天工具。

Web 方面的烦恼,欢迎随时咨询。

案例分析