ruby-on-rails - PostgreSQL + rails : is it possible to have a write-only database user in PG?

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

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

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

想法是拥有一个“writer”类型的用户,它使用一个单独的数据库连接。应该允许此连接插入/更新/删除但不允许选择。

我已经很好地设置了一切,但不幸的是 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 中向 writer 用户授予“有限的”SELECT 权限,因此他们只能“查看”某些列。我完全不知道这是否可能。
  2. 让 Rails 在查询末尾不添加“RETURNING id”,尽管这可能会产生副作用。

我找到了一篇文章,有人遇到了同样的问题,最后只是向作者用户授予了 SELECT 权限:

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

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

最佳答案

自 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

用户只能看到他放入数据库的最后一行。反正他知道那是什么。

关于ruby-on-rails - PostgreSQL + rails : is it possible to have a write-only database user in PG?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43641326/

相关文章:

ruby-on-rails - 在上传到 S3 之前,如何在服务器上将文件验证为图像?

ruby-on-rails - Rails Redis 排行榜

sql - 按事件和非事件日期计算单位数

c# - 如何在 select 查询中添加 where 子句

ruby-on-rails - 如何整合多个rails应用并共享资源

ruby-on-rails - 如何将 "where not"子句与 searchkick 一起使用

sql - 当 ForeignKey null=True 时 Django 慢查询

postgresql - 将数据从 postgres 索引到 solr/elasticsearch

android - Google Chrome for Android <select> 元素不选择任何选项

Mysql 在子选择中使用 GROUP_CONCAT