关于

了解如何通过启用行级安全和在Supabase仪表板中编写Postgres策略来限制对数据库表的访问。

观察

确保你的数据表安全

在Supabase中,你可以直接从客户端(通常是网络浏览器)访问你的数据,你可以这样做,把你的Supabase URL和Anon密钥传递给supabase-js:

  const supabase = createClient(
  'https://qwertyuiop.supabase.co',
  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
)
  

然而,这引起了一个有趣的问题:“如果我的匿名密钥在客户端,那么就不会有人阅读我的javascript并窃取我的密钥吗?",答案是肯定的。而这正是Postgres策略的作用所在。

使用Postgres的 行级安全策略,我们可以对匿名钥匙默认允许或不允许访问的数据设置规则。

例如,我们可以说匿名钥匙只能从一个特定的表中读取,但不能写入、更新或删除。

而且这些规则可以随我们的意愿而复杂。我们可以说,匿名键只能删除在星期四下午4点到6点之间插入的行,并且id列是偶数。很奇怪,但它显示了策略的力量。

比方说,我们创建了一个排行榜表。我们希望网站上的人能够阅读排行榜,但不能写入、更新或删除它。我们首先在SQL中定义我们的表并添加一些假数据:

  create table leaderboard (
    name text,
    score int
);

insert into leaderboard(name, score)
values ('Paul', 100), ('Leto', 50), ('Chani', 200);
  

现在让我们设置一个客户端来读取数据,我在这里创建了一个副本来展示一个活生生的例子。https://replit.com/@awalias/supabase-leaderboard-demo#index.js。如果你复制这个片段,你可以插入你自己的Supabase URL和anon key。

你可以看到,通过使用,可以自由地从表中读取和写入。

  // Writing
let { data, error } = await supabase.from('leaderboard').insert({ name: 'Bob', score: 99999 })

// Reading
let { data, error } = await supabase
  .from('leaderboard')
  .select('name, score')
  .order('score', { ascending: false })
  

现在我们来限制访问。我们将从完全限制该表开始。我们可以在SQL编辑器中通过做一个查询来做到这一点。

  ALTER TABLE leaderboard ENABLE ROW LEVEL SECURITY;
  

或通过 Supabase 仪表板,导航到 Auth > Policies,并单击 leaderboard 表上的红色挂锁,使其变成白色。

你会注意到,现在读和写都失败了,出现了类似的错误:

  {
  hint: null,
  details: null,
  code: '42501',
  message: 'new row violates row-level security policy for table "leaderboard"'
}
  

现在我们需要添加一个策略,使每个在 “授权 “中发送匿名密钥(JWT)的人能够读取该表。Bearer “头的人。

在SQL中,这可以通过以下方式完成。

  CREATE POLICY anon_read_leaderboard ON leaderboard
    FOR SELECT
    TO 'anon'
    USING (true);
  

anon_read_leaderboard这里只是你为你的策略选择的一个名字。leaderboard是表的名称。FOR SELECT表示我们只希望这个策略适用于读取(或者说SQL中的 “选择”)。TO意味着这个策略只适用于anonPostgres角色。最后,规则本身是 “true”,这意味着它将允许任何 “选择 “给 “anon “用户。

如果你喜欢使用仪表板来添加你的策略,你可以通过点击策略标签中的 “添加策略 “来完成,并制定一个类似这样的策略。

现在你应该能够从你的排行榜上读取信息,但仍然不能写入、更新或删除,这正是我们想要的

快速提醒你,你总是可以使用你的service_roleAPI密钥来绕过这些行级安全策略。但是要格外小心,不要把这个密钥包含在客户端中,以免泄露。如果你正在建立内部管理工具,或者你需要通过API批量插入或删除数据,这可能很有用。

在下一篇指南中,我们将探讨如何将策略与用户账户结合起来使用,这样你就可以在用户的基础上限制对数据的访问。观看第三部分:策略

资源

下一步