Postgresql:删除查询表中每一行的功能

von4xj4u  于 2022-11-04  发布在  PostgreSQL
关注(0)|答案(2)|浏览(233)

我把下面的表称为“概要”:
SELECT * FROM profile
每个用户(使用SupaBase)在“profile”表中都有自己的行,其user_id作为关键字(id)
我添加了RLS,以便只有用户可以更新/删除自己的行,但其他人只能选择该行(任何人都可以看到他的配置文件)
这样做效果很好,但问题是有人可能会使用SELECT * FROM profile或类似的语句查询表中的每个用户。我只希望人们能够使用WHERE语句查看已经有了“id”或“name”的行。
我看到的唯一解决方案是删除SELECT表的功能(基本上使其成为私有表),并创建一个使用管理密钥进行查询的API(绕过RLS)。这样,没有人可以查询整个表,客户端只需调用API,然后API将查询数据。
但是,我想直接从客户端查询,所以我想知道是否有一个不同的解决方案,不需要API之间。目前正在学习Postgresql,所以我可能错过了一些真正简单的东西。

332nm8kg

332nm8kg1#

您无法在行级安全策略中获得下划线查询,因此无法实现您所寻找的确切解决方案,但有一种解决方法。
您可以拒绝选定用户的所有访问,然后创建以下数据库函数。末尾的security definer表示此函数将绕过行级安全性。

create or replace function get_user(user_id uuid)
returns public.users
language sql
as
$$
  select * from public.users where id = get_user.user_id;
$$ security definer;

有了上面的函数,您就可以从客户端查询数据,如下所示:

const { data, error} = await supabase.rpc('get_user', { user_id: 'target_user_id_to_query' })

这样,任何人都只能在知道用户的user_id的情况下查询用户,并且您仍然可以直接从客户端查询用户。

7lrncoxx

7lrncoxx2#

请参阅Row Security Policies页面,其中有一个与您的场景完全相同的示例:
在表上启用行安全性(使用ALTER TABLE ... ENABLE ROW LEVEL SECURITY)时,行安全策略必须允许对表进行所有正常访问以选择行或修改行。
[...]
如果未指定角色,或使用特殊的使用者名称PUBLIC,则原则会套用至系统上的所有使用者。若要允许所有使用者只存取使用者表格中他们自己的数据列,可以使用简单的原则:

CREATE POLICY user_policy ON users
    USING (user_name = current_user);

相关问题