我们正在构建一个位于postgres数据库之上的Web应用程序。我们希望在数据库中实现授权逻辑,以使其对应用程序不透明。例如,假设服务器端控制器从视图v_user请求所有用户。我们希望db能够处理当前登录用户可以或不能看到的用户的授权。显然,服务器需要在每次请求时发送login_pkey(登录用户的user_pkey)才能生效。
我们遇到的问题是阅读。我们能够通过将触发器中的逻辑放在所有视图上的这些操作后面来实现插入,更新和删除。我们遇到的问题是如何为读取执行此操作。我们如何在视图(或其他地方)中包含变量逻辑(即依赖于传递login_pkey的逻辑)以及如何为每个查询传递此信息。
如果重要,我们使用的服务器是Node,ORM是Sequelize。
提前致谢。
答案 0 :(得分:0)
使用Pl / Python全局字典GD实现这一点非常容易。首先,您需要编写auth()函数:
create or replace function auth(login text, pass text) as $$
-- Check auth login here
GD['user_id'] = get_user_id_by_login(login)
$$ language plpythonu;
然后你必须编写get_current_user()函数
create or replace function get_current_user() returns integer as $$
return GD['user_id']
$$ langugage plpythonu;
现在,您可以随时获得当前用户。例如:
-- inside stored procedure
vUserId := get_current_user()
-- in query
select * from some_table where owner_id = get_current_user()
请记住,GD是按会话存储的,因此,正如您所写,每次连接数据库时都需要登录。在我的ORM中,我喜欢这样:
class MyORM():
def login(self, user, password):
cursor = self.__conn.cursor()
result = cursor.execute('select core.login(%s, %s)', (user, password,))
data = cursor.fetchone()
cursor.close()
return data[0]
def auth(self, cursor):
cursor.execute('select core.auth(%s)', (g.user_id,))
def query(self, query):
cursor = self.__conn.cursor()
self.auth(cursor)
cursor.execute(query)
data = cursor.fetchall()
cursor.close()
return data
答案 1 :(得分:0)
理想情况下,你真的希望row security做得好。它现在可以在9.5版本的测试版中使用。
但是你可以在没有的情况下做你需要的事。
要传递用户身份,您可以使用自定义变量,例如
SET myapp.appuser = 'fred';
然后使用current_setting
例如
SELECT current_setting('myapp.appuser')
如果设置不存在,这将引发ERROR
,因此您应该在postgresql.conf
中设置默认空白值,ALTER DATABASE SET
等。或者使用PostgreSQL 9.5&#39 ; s current_setting('settingname', true)
在缺失值上返回null。
要过滤用户可以看到的内容,请根据上述内容使用查看应用在连接时设置的用户身份设置的视图。
如果您的用户可以运行任意SQL,这是不安全的,因为没有任何事情阻止他们RESET
设置或执行SET myapp.appuser = 'the-admin'
。