基于数据库的Web应用程序审计日志需要用户ID

Tho*_*ing 4 sql postgresql audit triggers stored-procedures

我有一个Web应用程序,目前只支持PostgreSQL作为后端,并拥有自己的用户管理.使用Postgres身份验证机制使用通用用户帐户完成与数据库的连接.此应用程序现在应该只为基于触发器和存储过程的某些已创建和已更改的数据获取审计日志,并且出于性能原因,如果所有内容都与Web应用程序异步并且独立,则会很好.

有一个主要问题:我们想知道Web应用程序的哪个用户进行了一些更改或创建了数据,但是这些信息通常在存储过程中不可用,因为我们使用通用帐户连接到Postgres.我想避免做的是调用Web应用程序中的存储过程并以这种方式提供用户ID,因为这意味着在Web应用程序中的可能位置添加相关调用.除此之外,我们使用没有Web应用程序的数据库直接更新数据模型,这意味着我们在任何情况下都需要触发器.

目前,Web应用程序正在处理在每个请求上启动的事务并在其结束时提交.因此,我在每个请求中在事务中创建一个临时表,它始终获取请求的当前用户ID,该请求应该可用于由创建或更改的数据上的触发器执行的存储过程.

我不知道的一些事情是,执行的存储过程是否甚至可以访问数据库的当前事务,因此能够从临时表中检索当前用户ID?该表不是为其创建触发器的已更改数据的一部分.如果每个请求创建一个临时表以在最坏的情况下只存储一个Integer,性能将如何受到影响?如果触发器能够访问临时表,则请求可以随时完成,因为它的工作已完成或有错误.这将如何影响一个触发器,该触发器将访问临时表,该临时表仅在存储过程想要读取用户ID的情况下在提交或恢复的事务中退出?

有没有其他方法可以将用户ID映射到触发器可以访问的事务的某个唯一标识符?除了一个临时表,我可以创建一个普通的表,在每个请求的开始,我将用户id映射到事务id,但独立于当前事务.如果触发器现在将获得负责执行触发器的事务id,则存储过程可以使用事务id来查找使用该事务的用户id.

有什么想法吗?谢谢!

我添加了一个关于触发器生命周期和执行上下文的问题,这个问题符合这个问题:

PostgreSQL中数据库触发器的执行上下文

Dan*_*ité 6

当你可以使用会话设置时,临时表似乎有点过分.

在版本9.1之前,需要postgresql.conf通过 custom_variable_classes参数声明自定义会话变量,这使得它在部署方面有点麻烦.

从9.2开始,它就不再需要了.所以你可以在连接时发出:

SET myapp.myusername='foobar';

然后在触发器中或实际上在会话中的任何地方SELECT current_setting('myapp.myusername'),或者SHOW myapp.myusername将返回值.