这件事什么时候做?(精确的时机)
时机很清楚,也没得商量:就在你发布应用、或把它交给真实用户之前。 当你只是一个人在自己电脑上测试时,什么都不会发生。但在你的应用连上互联网、装着别人数据的那一秒,没有这几把锁,你就是把一切都暴露了出去。而由于 AI 不会自己去做这件事(它想的是让应用能跑,而不是保护它),所以得由你明确地提出要求。
第 1 把锁 · RLS(让每个人只看到属于自己的东西)
没有 RLS,一个恶意用户只需要在 URL 或一个请求里改一改某个 ID,就能看到另一个人的数据。这是在使用 Supabase 和 PostgreSQL 的应用里最常见的漏洞——也是最容易被利用的。这就是为什么它是第 1 把锁。
我在用 Supabase 搭配 PostgreSQL。我有这些表:[列出你的表和它们的用户列,例如:posts (user_id)、comments (post_id, user_id)]。 请配置 Row-Level Security,让每个用户只能查看/编辑/删除属于自己的记录。请遵循 Supabase 的官方最佳实践: - 在所有表上启用 RLS(ENABLE ROW LEVEL SECURITY)。 - 为 SELECT、INSERT、UPDATE 和 DELETE 分别创建独立的策略(不要用 FOR ALL)。 - 对性能很重要:把用户函数包装成 (SELECT auth.uid()),而不是裸用 auth.uid(),这样 Postgres 每次查询只求值一次,而不是每行求值一次。 - 把策略限制到 authenticated 角色(TO authenticated),而不是 public,这样匿名访客根本碰不到这张表。 - 绝对不要在策略里用 user_metadata(用户可以修改它)。 - 在策略用到的列上加索引(例如 user_id)。 - 记住:要让 UPDATE 生效,还需要一个 SELECT 策略。 - 给我完整的、可以直接贴到 Supabase SQL Editor 里的 SQL,并用一行话解释每个策略做什么。
auth.uid()。但这会让 Postgres 每一行都求值一次——在一张 100.000 行的表里,差别就是一次 5 毫秒的查询和一次足足 5 秒的查询之间的差距!技巧(由 Supabase 官方文档记载)是:把它写成 `(SELECT auth.uid())`。这样它只会求值一次。这就是为什么上面的提示词里明确地要求了这一点。- 在你的应用里创建两个测试用户。
- 用用户 A 登录,创建一条记录。
- 用用户 B 登录:他不应该看到 A 的记录。
- 查看 Supabase 的 Security Advisor:如果你有哪张表忘了开 RLS,它会提醒你。
第 2 把锁 · CORS(谁可以调用你的 API)
请在我的后端配置 CORS,让**只有**我的生产域名(https://mi-app.com)和开发环境的 localhost 能够发起请求。 - 生产环境中不要用 "*" 作为允许的来源。 - 只允许我真正用到的方法(例如 GET、POST、PUT、DELETE)。 - 只允许我需要的请求头。 - 根据我的技术栈准确告诉我每样东西该放在哪里:[告诉它你的框架/后端]。
Access-Control-Allow-Origin: *。这就像敞着门,还挂了块牌子写着「请进,钥匙我留在里面了」。如果你的 AI 为了「让它快点跑起来」给你这样配置了,在发布前把它改掉。第 3 把锁 · Security Headers(给浏览器的防御指令)
请给我的应用添加推荐的安全 headers:Content-Security-Policy、X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Strict-Transport-Security (HSTS) 和 Permissions-Policy。 - 用一行简单的话解释每一个是做什么的。 - 给我针对我的框架、可以直接用的配置:[告诉它你用哪个,例如 Next.js、Express]。 - 先以 report-only 模式启动 Content-Security-Policy,这样不会弄坏任何东西,再告诉我之后怎么把它收紧。 - 告诉我怎么验证结果。
习惯 · 每次发布前都过一遍
- 在所有存有用户数据的表上启用 RLS(并用 2 个账户测试过)。
- CORS 限制到你自己的域名,绝不在启用凭据时用
*。 - Headers 配置好了,并在 securityheaders.com 上拿到 A 评分。
- 你的密钥(.env、API 密钥)从不上传到 GitHub(见本系列的 GitHub 指南)。
- 你查看了 Supabase 的 Security Advisor,没有红色的告警残留。