pg-promise одно подключение на пользователя

Уважаемое сообщество и, надеюсь, 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, чтобы избежать этого уродливого пользовательского объекта «пул»?

Искренне благодарю вас.


person alexnode    schedule 28.08.2017    source источник
comment
Это вообще не выглядит правильно. Но если позволите, зачем вам это? Такое решение не может масштабироваться, так как подключения являются наиболее ценным ресурсом, которым необходимо делиться, чтобы обеспечить масштабируемость. Вы намеренно пытаетесь помешать своему служению.   -  person vitaly-t    schedule 28.08.2017
comment
Привет, Виталий-т. Спасибо за оперативный ответ. Не могли бы вы перефразировать? Такое решение не может масштабироваться, так как соединения являются наиболее ценным ресурсом, которым необходимо делиться, чтобы быть масштабируемым, пожалуйста. Я хочу сделать это, чтобы повысить безопасность. У каждого пользователя должно быть свое подключение к pg, не так ли? Я нигде не могу найти, как обрабатывать несколько пользователей с помощью postgres. Должен ли я иметь только 1 подключение к pg (admin) на моем сервере? Я хотел бы использовать функцию уровня безопасности строки postgres.   -  person alexnode    schedule 28.08.2017
comment
ИЛИ каждый раз, когда я хочу выполнить запрос, мне нужно изменить глобальную переменную соединения вашего примера здесь? : stackoverflow.com/questions/8484404/   -  person alexnode    schedule 28.08.2017
comment
@vitaly-t, похоже, что все примеры в Интернете имеют своего рода пароль администратора и идентификатор для всех запросов, независимо от того, к какому пользователю подключен. Я не понимаю, как я могу использовать для этого функцию уровня безопасности строки pg-promise. Либо я ничего не понимаю, либо делаю что-то, чего раньше никогда не делал.   -  person alexnode    schedule 30.08.2017
comment
Привет, я связался с ответственным за безопасность моего проекта, проводя исследование доцента в области безопасности (лаборатория CITI)...   -  person alexnode    schedule 07.09.2017
comment
@alexnode, у меня точно такая же проблема. Из того, что я прочитал до сих пор, все примеры, похоже, используют уникальное соединение. Для меня это не имеет смысла с точки зрения безопасности. Мы должны иметь возможность создать одно соединение для каждого пользователя (с его идентификатором и паролем). В противном случае это означало бы, что кто-то, кто может получить доступ к вашему серверу, может получить доступ к БД... довольно плохо. В итоге я сбросил &cn объекта db. Но не уверен, что это хорошая практика. Пока работает...   -  person RomOne    schedule 18.09.2017
comment
@alexnode, пожалуйста, дайте мне знать о ходе вашей работы по этому вопросу. Я также хочу использовать 4-5 разных пользователей (зарегистрированных, незарегистрированных, администраторов, сотрудников и т. д.) в целях безопасности. Тиа   -  person SONewbiee    schedule 16.07.2018


Ответы (1)


Я связался с ответственным за безопасность моего проекта, проводя исследования в качестве доцента в области безопасности (лаборатория CITI)... вот его комментарий:

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

Так как это моя вина, я попытаюсь объяснить ;-). Во-первых, чтобы внести ясность, я занимаюсь вопросами безопасности (в частности, контролем доступа и безопасностью СУБД), но не очень знаком с JS или промисами.

Наша цель состоит в том, чтобы реализовать принцип наименьших привилегий с подходом глубокоэшелонированной защиты. В данном конкретном случае это означает, что запрос, отправленный непривилегированным пользователем, не должен иметь прав администратора на стороне базы данных. РСУБД, такие как PostgreSQL, предоставляют очень мощные, выразительные и хорошо протестированные механизмы управления доступом: RBAC, безопасность на уровне строк, параметризованные представления и т. д. Действительно, эти элементы управления обычно полностью игнорируются в веб-приложениях, использующих парадигму «1 приложение ==». 1 пользователь», таким образом, этот пользователь имеет роль администратора. Но тяжелые клиенты часто используют несколько разных пользователей на стороне базы данных (по одному на конечного пользователя или по одному на определенную роль) и, таким образом, выигрывают от контроля доступа к базе данных.

Контроль доступа из БД является дополнением к контролю доступа в веб-приложении. AC в веб-приложении будет более точным, но, вероятно, может иметь некоторые ошибки; AC в БД будет немного менее строгим, но лучше соблюдается, ограничивая ущерб в случае ошибки приложения.

Итак, в нашем случае мы хотим создать пользователя БД для каждого пользователя приложения. Затем соединение с базой данных принадлежит этому конкретному пользователю, и, таким образом, база данных может гарантировать, что простой пользователь не может выполнять операции администратора. В качестве промежуточной возможности можно было бы отказаться от некоторых привилегий перед выполнением запроса, но наш предпочтительный способ — подключиться к базе данных в качестве текущего пользователя, вошедшего в систему. Логин-пароль присылается пользователем при аутентификации и мы просто передаем его в СУБД. Масштабируемость (пока) не является проблемой для нашего приложения, мы можем пожертвовать некоторой масштабируемостью ради этого типа безопасности.

У вас есть какие-нибудь подсказки, которые помогут нам достичь этого?

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

person alexnode    schedule 07.09.2017
comment
Я задал вопрос с другим сообщением, так как это, в частности, не касается pg-promise: stackoverflow.com/questions/46099931/ - person alexnode; 07.09.2017