PostgreSQL + Rails:PG中是否可以有一个只写数据库用户?

时间:2017-04-26 17:55:55

标签: ruby-on-rails postgresql select permissions grant

我正在Ruby on Rails中构建一个JSON API。我希望有一个只写用户帐户,该帐户应该向系统提供数据,但不应允许其从中读取数据。

为了实现额外的安全层,我想在数据库级别强制执行此规则。

这个想法是要有一个"作家"使用与数据库的单独连接的用户类型。应允许此连接插入/更新/删除,但不允许选择。

我已经很好地设置了所有内容但不幸的是Rails在插入时生成了这个查询:

INSERT INTO "default"."products" ("id", "name", "sku") VALUES ($1, $2, $3) RETURNING "id"

" RETURNING id"部分是因为用户没有SELECT权限而失败:

ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR:  permission denied 
for relation products: 
INSERT INTO "default"."products" ("id", "name", "sku") VALUES ($1, $2, $3) RETURNING "id"

有没有办法在PG或Rails中解决这个问题?我看到的两个选项是:

  1. 授予"限制" PG中编写者用户的SELECT权限,因此他们只能"看到"一些专栏。我根本不知道这是否可行。
  2. 让Rails不添加" RETURNING id"在查询结束时,虽然这可能有副作用。
  3. 我找到了一篇有同样问题的人的文章,结果只是向作家用户授予SELECT权利:

    https://til.hashrocket.com/posts/0c83645c03-postgres-permissions-to-insert-but-not-return

    有可能有一个实际的解决方案让上面的设置工作吗?

1 个答案:

答案 0 :(得分:3)

自PostgreSQL 9.5以来,有一种方法可以使用行级安全功能:

create table products(id serial primary key, name text not null, sku text not null);
grant select,insert on products to tometzky;
grant usage on sequence products_id_seq to tometzky;
alter table products enable row level security;
create policy products_tometzky on products to tometzky
  using (id=currval('products_id_seq'));

tometzky=> select * from products;
ERROR:  currval of sequence "products_id_seq" is not yet defined in this session
tometzky=> insert into products (name, sku) values ('a','a') returning id;
1
tometzky=> select * from products;
1|a|a
tometzky=> insert into products (name, sku) values ('b','b') returning id;
2
tometzky=> select * from products;
2|b|b

用户只能看到他放入数据库的最后一行。无论如何,他都知道它是什么。