當你把資料庫的鑰匙交給了前端網頁
在傳統的軟體架構中,資料庫就像是一個深藏在地下室的保險箱。前端的網頁(瀏覽器)是絕對無法直接碰到這個保險箱的。網頁必須要透過「後端伺服器 (如 Node.js 或 Python)」作為警衛,由警衛檢查使用者的證件後,警衛再親自下樓去保險箱拿資料。
但隨著雲端技術與 Supabase 的崛起,現在流行一種名為 「無後端 (Serverless / Backend-as-a-Service)」 的開發架構。
在第二章中,我們教你把 Supabase 的 anon_key 直接放進了 .env.local 裡,讓 Next.js / React 前端網頁直接連線到資料庫抓資料。
這帶來了前所未有的開發速度,但同時也伴隨著一個巨大的資安漏洞:萬一有心人士在網頁上按了 F12 開發者工具,把你的 anon_key 偷走怎麼辦?
如果他拿著這把鑰匙,寫了一段小腳本,對你的資料庫下達了 DELETE FROM users(刪除所有會員)的指令,你的心血不就瞬間歸零了?
為了解決這個致命問題,PostgreSQL 祭出了它最引以為傲的終極防禦武器:RLS (Row-Level Security,行級安全性)。
什麼是 RLS?為每一行資料派駐一位隨身保鑣
傳統的資料庫權限,就像是「大門門禁」。一旦駭客突破了大門進入了 orders (訂單) 表格,他就可以看見所有人的訂單。
而 RLS (Row-Level Security) 的概念完全不同。它就像是在表格裡的「每一行 (Row)」旁邊,都站著一位荷槍實彈的保鑣。
當駭客拿著 anon_key 試圖想要拿走王大明的訂單時,保鑣會立刻攔住他:
「請出示你的 JWT 通行證!你必須證明你是『王大明本人』,我才允許你把這行資料拿走。否則,你在這張表裡什麼都看不到!」
有了 RLS 的保護,即使你的 anon_key 不小心外洩,駭客也無能為力。因為 anon_key 只是讓他能「敲門」,而 RLS 才會決定「門後有什麼東西」願意顯示給他看。
RLS 的核心心法:Policy (政策)
在 Supabase 中,你要如何訓練這些保鑣呢?你需要為每個表格寫下名為 Policy (政策) 的法律條文。
政策通常包含兩個要素:
- 能做什麼事 (Action):例如
SELECT(讀取)、INSERT(新增)、UPDATE(修改)、DELETE(刪除)。 - 什麼條件下允許 (USING / WITH CHECK):例如「當目前登入者的 ID 等於這行資料的 user_id 時」。
常見的 RLS 商業情境設定
情境一:公開的商品目錄 (所有人都能看)
對於 products (商品表),我們希望不管是登入的會員,還是路過的訪客,都可以看到商品資訊。但是不允許任何人修改或刪除商品。
- 動作:允許
SELECT。 - 條件:
true(無條件允許所有人)。 - (附註:因為我們沒有寫
INSERT或UPDATE的 Policy,所以任何試圖修改商品的動作都會被保鑣直接擋下!)
情境二:私人的購物車與訂單 (只有自己能看自己的)
對於 orders (訂單表),這是極度隱私的資料。王大明只能看到王大明的訂單,絕對不能看到陳小美買了什麼。
- 動作:允許
ALL(包含查詢、新增、修改、刪除)。 - 條件:這行資料的
user_id必須等於 目前登入使用者的 UID (auth.uid())。
實戰:用 Vibe Prompt 秒解 RLS 設定難題
RLS 雖然強大,但它的 SQL 語法非常冗長且容易寫錯。在 Vibe Coding 中,你絕對不應該自己手寫 RLS 政策。
當你在 Supabase 開發時,如果遇到「資料明明有存進去,但是前端怎麼撈都是一片空白」的情況,恭喜你,你 100% 撞到 RLS 防火牆了。這時候,請開啟 Cursor 的 SQL Editor,對著 AI 下達這段終極解鎖咒語:
【Supabase RLS 解鎖 Prompt】 我正在使用 Supabase。我有一個名為
user_profiles的表格,欄位有id(關聯到 auth.users),nickname,avatar_url。 目前因為 RLS 的關係,我的前端網頁無法讀取或更新資料。 請幫我寫一段完整的 SQL 腳本,完成以下 RLS 政策設定:
- 開啟
user_profiles的 RLS 功能 (ENABLE ROW LEVEL SECURITY)。- 建立第一條 Policy:允許「任何人 (包含匿名訪客)」讀取 (
SELECT) 所有人的資料。- 建立第二條 Policy:只允許「使用者本人」可以修改 (
UPDATE) 或新增 (INSERT) 屬於自己的資料 (條件是 auth.uid() 等於這行資料的 id)。 請確保語法完美相容於 Supabase 的 PostgreSQL 環境。
AI 產出的神級保鑣訓練腳本:
-- 1. 喚醒表格的保鑣系統 (開啟 RLS)
ALTER TABLE user_profiles ENABLE ROW LEVEL SECURITY;
-- 2. 政策一:所有人都可以看 (SELECT)
CREATE POLICY "Public profiles are viewable by everyone"
ON user_profiles
FOR SELECT
USING (true);
-- 3. 政策二:只有本人可以新增 (INSERT)
CREATE POLICY "Users can insert their own profile"
ON user_profiles
FOR INSERT
WITH CHECK (auth.uid() = id);
-- 4. 政策三:只有本人可以修改 (UPDATE)
CREATE POLICY "Users can update own profile"
ON user_profiles
FOR UPDATE
USING (auth.uid() = id);
你只需要把這段腳本複製,貼到 Supabase 的 SQL 控制台按下執行。 瞬間,你的資料庫就獲得了軍用級別的安全防護。你可以安心地把你寫好的網頁交給客戶,再也不用擔心駭客把資料庫搞砸了!
恭喜您!完成本章節後,您已經完全掌握了現代資料庫從「架設、關聯運算、加密、到最高級的 RLS 資安防護」的完整生態系。身為一個強大的 Vibe Coder,世界上的所有數據現在都任您差遣了!