首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >即使通过postgres控制台中的插入工作,由于RLS导致Supabase insert失败

即使通过postgres控制台中的插入工作,由于RLS导致Supabase insert失败
EN

Stack Overflow用户
提问于 2022-04-19 14:48:22
回答 1查看 651关注 0票数 0

我在supabase中实现了一个身份验证框架,它支持具有不同权限的多个角色,从而为不同的场景创建多个策略。

我的所有策略都包含了一组集成测试,以确保连续性。

我面临的一个特殊问题是,supabase JS中的INSERT语句由于行级验证而失败,即使通过与Posgres控制台中的SQL语句相同的INSERT语句也是如此。

我有一个表clients,大致定义为

代码语言:javascript
运行
复制
CREATE TABLE clients (
  id serial primary key,
  name varchar
);

ALTER TABLE clients ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Allow client_admin to create new record if none exist" ON clients
    FOR INSERT TO authenticated
    WITH CHECK (
        auth.is_user_in_group(auth.uid(), 'client_admin')
        AND auth.client_ids() IS NULL
    );

我的测试如下所示

代码语言:javascript
运行
复制
// Given
const newUser = await createUser({
  email: 'new_client+test@example.com',
})
await logInAs(newUser)

// When
const { data, error } = await anonClient
  .from('clients')
  .insert([generateClient({}).record])

注意:generateClient(...)函数只生成具有随机数据的对象,不执行任何插入操作。

该insert语句在

代码语言:javascript
运行
复制
{"code": "42501", "details": null, "hint": null, "message": "new row violates row-level security policy for table \"clients\""}

即使我在DataGrip中打开一个控制台并执行

代码语言:javascript
运行
复制
SET "request.jwt.claim.sub" TO '6aab88c8-6cc9-48fa-a90a-d45bfdc4a055';
SET ROLE authenticated;

INSERT INTO clients(name) VALUES (gen_random_uuid());
INSERT INTO clients(name) VALUES (gen_random_uuid());

第一次插入有效,而第二次插入按预期失败。

为了使这个实验变得干净,我甚至尝试了以下的策略

代码语言:javascript
运行
复制
CREATE POLICY "Allow client_admin to create new record if none exist" ON clients
    FOR INSERT TO authenticated
    WITH CHECK (
      true
    );

我甚至试图删除所有其他政策,以确保它们不会以某种方式干预。

知道我在哪里会犯错误吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-19 15:15:25

就像经常发生的那样,几乎是在发完帖子之后,我就想出了答案。

我一直在阅读SQL查询日志,发现supabase还会尝试在insert之后立即选择数据。

大致看上去

代码语言:javascript
运行
复制
INSERT INTO clients(name) VALUES (gen_random_uuid()) RETURNING clients.*;

我有一个触发器,该触发器将一个新记录插入到client_users表并影响SELECT策略。

很明显,这里发生的是:

代码语言:javascript
运行
复制
TRANSACTION STARTS
INSERT to clients
RETURNING clients.* <--- FAILS RLS AND REVERTS TRANSACTION
INSERT to client_users <--- Should let SELECT RLS work, but fails due to order of operations

对于那些面临同样问题的人来说,似乎有两种选择:

  • 配置选择不返回任何信息的策略
  • Do supabase insert

代码语言:javascript
运行
复制
const { data, error } = await anonClient
  .from('clients')
  .insert(generateClient({}).record, {
    returning: 'minimal',
  })
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71926947

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档