Postgresql 如何在Posgres数据库中实现数据授权逻辑?

Postgresql 如何在Posgres数据库中实现数据授权逻辑?,postgresql,Postgresql,我们正在构建一个位于postgres db之上的web应用程序。我们希望在数据库中实现授权逻辑,以便对应用程序不透明。例如,假设服务器端控制器从视图v_用户请求所有用户。我们希望db能够处理当前登录用户可以看到或无法看到的用户的授权。显然,服务器需要在每个请求上发送login_pkey(登录用户的user_pkey)才能使其工作 我们面临的问题是阅读。我们可以通过将逻辑放在所有视图上这些操作背后的触发器中,来完成插入、更新和删除操作。我们面临的问题是如何为reads执行此操作。我们如何在视图(或

我们正在构建一个位于postgres db之上的web应用程序。我们希望在数据库中实现授权逻辑,以便对应用程序不透明。例如,假设服务器端控制器从视图v_用户请求所有用户。我们希望db能够处理当前登录用户可以看到或无法看到的用户的授权。显然,服务器需要在每个请求上发送login_pkey(登录用户的user_pkey)才能使其工作

我们面临的问题是阅读。我们可以通过将逻辑放在所有视图上这些操作背后的触发器中,来完成插入、更新和删除操作。我们面临的问题是如何为reads执行此操作。我们如何在视图(或其他地方)中包含变量逻辑(即,取决于传递哪个登录名的逻辑),以及如何为每个查询传递此信息

如果这很重要,我们使用的服务器是Node,ORM是Sequelize


提前感谢。

使用Pl/Python全局dict GD很容易实现这一点。首先,您需要编写auth()函数:

创建或替换函数auth(登录文本、传递文本)作为$$
--在此处检查身份验证登录
GD['user\u id']=通过登录获取用户id(登录)
$$language plpythonu;
然后必须编写get\u current\u user()函数

现在,您可以随时获取当前用户。例如:

-- inside stored procedure
vUserId := get_current_user()
-- in query
select * from some_table where owner_id = get_current_user()
记住,GD存储在每个会话中,所以,正如您所写的,每次连接到数据库时都需要登录。在我的ORM中,我喜欢这样:

class MyORM():
def登录(自我、用户、密码):
游标=自身。\u连接游标()
结果=cursor.execute('select core.login(%s,%s)'(用户,密码,))
data=cursor.fetchone()
cursor.close()
返回数据[0]
def auth(自我,光标):
cursor.execute('select core.auth(%s)'(g.user\u id,)
def查询(自我,查询):
游标=自身。\u连接游标()
self.auth(游标)
cursor.execute(查询)
data=cursor.fetchall()
cursor.close()
返回数据
理想情况下,你真的想把这件事做好。它现在在9.5版本的beta版中提供

但你可以做你需要的事,不用担心


要传递用户标识,可以使用自定义变量,例如

SET myapp.appuser = 'fred';
然后使用
当前设置访问它,例如

SELECT current_setting('myapp.appuser')
如果设置不存在,这将引发一个
错误
,因此您应该在
postgresql.conf
中使用
ALTER DATABASE set
等设置默认空白值,或者使用postgresql 9.5的
current\u设置('settingname',true)
在缺少值时返回null


若要筛选用户可以看到的内容,请使用在连接时检查应用程序设置的用户身份设置的视图,如上所述


如果您的用户可以运行任意SQL,这是不安全的,因为没有任何东西可以阻止他们重置设置或执行设置myapp.appuser='管理员'

@a_horse_with_no_name谢谢,修复了
SELECT current_setting('myapp.appuser')