Topics

在業務應用程式中如何運用 Supabase 的 RLS

  • column

大家好,我是 Liberogic 的 Matsun。

上一篇文章介紹了透過 Supabase Auth 與 Cloudflare 打造的驗證型網頁應用程式。本次則要接續探討當時簡單提到的 **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株式会社
 ├ 森本さん
 ├ 大塚さん
 └ 山田さん

假設有三位使用者,三人都能看到 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 相關問題。

案例分析