AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
[TOC] > [参考](https://zhuanlan.zhihu.com/p/605040081) ## 概述 **Row Level Security(行级安全)** 是 PostgreSQL 的内置安全机制,让你在数据库层控制: * 哪些行可以被读(SELECT) * 哪些行可以被写(INSERT/UPDATE/DELETE) 适用于: * 多租户系统(SaaS) * IM 系统按用户隔离消息 * 需要严格权限的业务系统 ## 启用 RLS ~~~ ALTER TABLE table_name ENABLE ROW LEVEL SECURITY; ~~~ 示例: ~~~ CREATE TABLE todos ( id SERIAL PRIMARY KEY, user_id INT NOT NULL, content TEXT, created_at TIMESTAMP DEFAULT NOW() ); ALTER TABLE todos ENABLE ROW LEVEL SECURITY; ~~~ * * * ## 🎯 创建行级策略(POLICY) ### 1\. SELECT(控制可见行) ~~~ CREATE POLICY select_own_todos ON todos FOR SELECT USING (user_id = current_setting('app.current_user_id')::int); ~~~ * * * ### 2\. INSERT(只能写自己的数据) ~~~ CREATE POLICY insert_own_todos ON todos FOR INSERT WITH CHECK (user_id = current_setting('app.current_user_id')::int); ~~~ * * * ### 3\. UPDATE(只能修改自己的数据) ~~~ CREATE POLICY update_own_todos ON todos FOR UPDATE USING (user_id = current_setting('app.current_user_id')::int) WITH CHECK (user_id = current_setting('app.current_user_id')::int); ~~~ * * * ### 4\. DELETE(只能删除自己的数据) ~~~ CREATE POLICY delete_own_todos ON todos FOR DELETE USING (user_id = current_setting('app.current_user_id')::int); ~~~ * * * ## 🧩 设置当前用户上下文(应用层必用) 在请求前设置当前用户: ~~~ SELECT set_config('app.current_user_id', '123', false); ~~~ 然后所有 SQL 都自动按 user\_id 限制访问。 * * * ## 🔐 强制所有用户遵守 RLS(包括表所有者) ~~~ ALTER TABLE todos FORCE ROW LEVEL SECURITY; ~~~ * * * ## 🧱 默认行为 启用 RLS 后,如果没有 policy: * 用户对该表 **无法 SELECT/INSERT/UPDATE/DELETE** 这是安全默认值,避免忘配策略导致泄露。 * * * ## 📘 完整可复制示例 ~~~ CREATE TABLE todos ( id SERIAL PRIMARY KEY, user_id INT NOT NULL, content TEXT, created_at TIMESTAMP DEFAULT NOW() ); ALTER TABLE todos ENABLE ROW LEVEL SECURITY; CREATE POLICY select_own_todos ON todos FOR SELECT USING (user_id = current_setting('app.current_user_id')::int); CREATE POLICY insert_own_todos ON todos FOR INSERT WITH CHECK (user_id = current_setting('app.current_user_id')::int); CREATE POLICY update_own_todos ON todos FOR UPDATE USING (user_id = current_setting('app.current_user_id')::int) WITH CHECK (user_id = current_setting('app.current_user_id')::int); CREATE POLICY delete_own_todos ON todos FOR DELETE USING (user_id = current_setting('app.current_user_id')::int); ALTER TABLE todos FORCE ROW LEVEL SECURITY; ~~~