pg-promise每个用户一个连接

4
亲爱的社区和Vitaly-t先生,
我正在使用pg-promise构建一个网站/服务器,使用postgre角色/组登录进行身份验证。
我不知道我是否做得正确,但我希望每个用户都使用自己的postgres连接查询数据库。
因此在实践中,当每个用户连接时(如果不存在),我为每个用户创建一个连接。 为此,我创建了一个Pool对象,带有一个丑陋的“虚假承诺”和一个pgUser对象:
var pgPool = function(pg){
    var _this=this;
    var fakePromise = function(err){
        var _this=this;
        _this.err=err
        _this.then=function(cb){if(!err){cb();return _this}else{return _this};};
        _this.catch=function(cb){if(err){cb(_this.err)}else{return _this};};
        return _this;
            };

    _this.check= function(user){
        if (_this[user]){
            return _this[user].check();
        }else{
            return new fakePromise({error:'Echec de connection à la base de 
            données'})
        }


    }
    _this.add = function(user,password){
        var c={};
        c.host = 'localhost';
        c.port = 5432;
        c.database = 'pfe';
        c.poolSize = 10;
        c.poolIdleTimeout = 30000;
        c.user=user;
        c.password=password
        if (!_this[user]){
            _this[user] = new pgUser(c,pg);
            return _this[user].check();
        }else{
            _this[user].config.password=password;
            return _this[user].check();
        };
    };
    return _this;
};

var pgUser = function(c,pg){
    var _this=this
    _this.config = c    
    _this.db = new pg(_this.config)
    _this.check = function(){
        return _this.db.connect();
    };
    return _this;
}; 

以下是我在登录POST处理期间将用户添加到“池”中的方法:

 pool.add(req.body.user,req.body.password).then(function(obj){
            obj.done();
            req.session.user = req.body.user;
            req.session.password = req.body.password;
            res.redirect("/");
            return;
        }).catch(function(err){
            options.error='incorect password/login';
            res.render('login', options);   
            return;
        });

我相信这可能会激怒专业的开发人员,如果您能解释一下最好的方法,那么您将是友善的:

  • 每个用户对数据库只有一个连接是否是个好主意(看起来确实可以提高安全性)?
  • 我该如何更好地使用pg-promise库,以避免使用这个丑陋的自定义“池”对象?

非常感谢。


1
你好,vitaly-t。感谢您的及时回复。请问您能否重新表述一下“这样的解决方案无法扩展,因为连接是最有价值的资源,需要共享才能实现可扩展性”这句话呢?我想这样做是为了增加安全性。每个用户都应该有自己连接到pg的方式,对吗?我找不到任何关于如何处理postgres多个用户的信息。我在我的服务器上只能拥有一个连接到pg(管理员)吗?我想使用postgres的行安全级别函数。 - alexnode
1
@vitaly-t,看起来网络上的所有示例都有一种管理员密码和ID,用于所有查询,无论用户是否连接。我不明白如何使用pg-promise的行安全级别函数来做到这一点。要么我什么也不懂,要么我正在做以前从未做过的事情。 - alexnode
1
嗨,我已经联系了我的项目的安全负责人,正在与安全副教授(CITI实验室)进行研究。 - alexnode
1
@alexnode,我遇到了完全相同的问题。根据我迄今所读的内容,所有的例子似乎都使用了唯一的连接。对于安全性来说,这对我来说没有意义。我们应该能够为每个用户创建一个连接(带有他们的ID和密码)。否则,这意味着可以访问您的服务器的人也可以访问数据库...非常糟糕。我最后重置了db对象的&cn。但不确定这是否是良好的做法。到目前为止它还在工作... - RomOne
1
@alexnode,请告诉我你在这个问题上的进展情况。出于安全考虑,我希望使用4-5种不同类型的用户(注册用户、未注册用户、管理员、员工等)。谢谢。 - SONewbiee
显示剩余2条评论
1个回答

1

我已经联系了负责我们项目的安全方面的人,他是一位在安全领域担任副教授的研究人员(CITI实验室)...这是他的评论:

====================

由于是我的错,我将尝试解释;-)。首先,明确一下,我从事安全方面的工作(特别是访问控制和RDBMS安全),但对JS或承诺不太熟悉。
我们的目标是采用深度防御的最小特权原则。在这种特定情况下,这意味着由非特权用户发送的查询不应具有数据库端的管理员权限。像PostgreSQL这样的RDBMS提供了非常强大、表达力强且经过充分测试的访问控制机制:RBAC、行级安全、参数化视图等。这些控件通常被完全忽略在使用“1应用程序==1用户”范例的Web应用程序中,因此该用户具有管理员角色。但是,重型客户端通常在数据库端使用几个不同的用户(每个最终用户一个或每个特定角色一个),因此受益于数据库的访问控制。
来自DB的访问控制是对Web应用程序中的访问控制的补充。Webapp中的AC将更加精确,但可能会遭受一些错误;DB中的AC将更加宽松,但执行得更好,在应用程序出现错误的情况下限制损害。
在我们的情况下,我们希望为每个应用程序用户创建一个DB用户。 然后,与数据库的连接属于此特定用户, 因此数据库可以强制执行普通用户无法执行管理员操作。一种中间可能性是在执行查询之前删除某些权限,但我们更喜欢以当前登录用户的身份连接到数据库。 登录密码由用户在进行身份验证时发送,我们只需将其传递给DBMS。 可扩展性对于我们的应用程序来说还不是一个问题,我们可以为这种类型的安全性牺牲一些可扩展性。
您有什么提示可以帮助我们实现这一点吗?

==================


我已经在另一篇帖子中提出了问题,因为这并不特别涉及pg-promise:https://stackoverflow.com/questions/46099931/webserver-with-database-one-connection-per-user - alexnode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接