Почему конфигурацию базы данных не следует хранить в приложении?
Мы видели, что в большинстве современных приложений nodejs конфигурация базы данных хранится в файле json внутри приложения. Мы также видели, что конфигурация базы данных с учетом среды поддерживается для доступа к конкретной базе данных в соответствии со средой, например. development.json будет иметь конфигурацию базы данных, которая будет запускаться в среде разработки.
Даже эти конфигурации игнорируются git, они могут быть легко уязвимы для пользователей, у которых есть правильный доступ к коду, а также большой головной болью поддерживать его в разных средах. Поэтому действительно необходимо избежать этой уязвимости, сохраняя конфигурации в зашифрованном виде.
Давайте посмотрим, как мы можем получить безопасный доступ к этим конфигурациям среды.
Поддерживайте единую главную базу данных
Нам необходимо поддерживать единую главную базу данных для хранения этих конфигураций в зашифрованном формате, доступ к которой можно получить с помощью ключа. В моем случае я использую PostgreSQL, который предоставляет расширение pgcrypto для криптографии.
Примечание. Даже если основная база данных доступна внутри кода, никто не сможет расшифровать ваши конфигурации без ключа шифрования.
Итак, давайте создадим базу данных:
-- create database CREATE DATABASE master_db_config;
Теперь у нас есть таблица для хранения конфигураций:
-- create table CREATE TABLE app_config( id SERIAL PRIMARY KEY, -- auto increment id config bytea, -- encrypted config env varchar(30), -- environment e.g. dev project_key varchar(30), -- unique project key is_active bool default true, createdon timestamp, updatedon timestamp );
Здесь id представляет идентификатор автоматического увеличения, config - столбец зашифрованных данных, env может быть для разработки, тестирования, производства и т. Д. project_key - уникальный идентификатор проекта.
Теперь давайте активируем расширение pgcrypto, используя:
-- this is required for running encrypt and decrypt functions CREATE EXTENSION pgcrypto;
Давайте вставим нашу первую конфигурацию для среды разработки:
INSERT INTO app_config(config, env, project_key, createdon, updatedon) VALUES ( encrypt( '{"host":"localhost","port":"5432","database":"myDb","user":"postgres","password":"root","max":"10","idleTimeoutMillis":"30000"}', 'ml9gi2r5ce275y3i8sxq', 'aes'), 'development', 'MY_WORST_PROJECT', '2018-09-29 10:01:00', '2018-09-29 10:01:00' );
Поэтому, если вы проверите этот запрос на вставку, функция шифрования передается как значение, а конфигурация JSON предоставляется в качестве аргумента для нее. ml9gi2r5ce275y3i8sxq - ключ для шифрования конфигурации, вы можете передать любую случайную строку, чтобы зашифровать ее. aes - алгоритм шифрования.
Примечание: вам нужно где-то надежно хранить этот ключ, так как вы не сможете расшифровать конфигурацию без ключа.
На этом мы завершаем настройку нашей основной БД. Итак, перейдем к коду.
Давайте закодируем
Я создал библиотеку для легкого доступа к вашим конфигурациям из Postgres, поэтому, прежде всего, добавьте ее в свои модули узлов, используя следующую команду:
npm install --save https://github.com/pravindot17/configprovider
Теперь у вас есть этот модуль, так что давайте использовать его в своем приложении.
let configProvider = require('configprovider'); let masterDbConfig = { "host":"localhost", "port":"5432", "database":"master_db_config", "user":"postgres", "password":"root", "max":"10", "idleTimeoutMillis":"30000" } // init the connection in your bootstrap file using following code configProvider.init(masterDbConfig, 'MY_SECRET_KEY', 'development', 'MY_WORST_PROJECT').then((appConfig) => { console.log('received the db config here in appConfig.dbConfig'); }).catch(console.error);
MY_SECRET_KEY: это секретный ключ, который использовался при вставке конфигурации базы данных в главную БД. Мы можем предоставить этот ключ в узле ENV во время развертывания или запуска вашего приложения. например Если вы запускаете свое приложение в разработке, мы можем передать DB_KEY = ’MY_SECRET_KEY’ в команде запуска npm, как показано ниже:
NODE_ENV="development" DB_KEY="MY_SECRET_KEY" node app.js
И получите доступ к нему в своем коде, используя process.env.NODE_ENV
и process.env.DB_KEY
Таким образом, мы получим конфигурацию нашей базы данных в нашем файле начальной загрузки, в основном app.js. Чтобы использовать его в любом месте приложения, просто используйте:
// to use it inside your application use following let dbConfig = configProvider.getConfig().dbConfig;
Примечание. Эта библиотека использует кеширование модулей, поэтому каждый раз, когда нам требуется эта библиотека в приложении, она не будет попадать в основную базу данных, за исключением файла начальной загрузки, в котором вызывается функция init.
Я также добавил некоторые функции, чтобы к нему можно было добавить существующую конфигурацию приложения, чтобы все приложение и конфигурация базы данных были легко доступны для всего приложения.
// You can also add more config to the cache configProvider.addConfig('appConfig', {"title": "My worst application", "isEmailRequired": true}); // You can also merge config into existing config configProvider.mergeConfig({"smsConfig": { "isEnabled": true, "content": "Have a good day!" }});
Заключение
Таким образом, мы можем легко получить конфигурации нашей базы данных без нарушения наших соединений с базой данных.
Спасибо за прочтение!
Если вам понравилась статья выше, хлопайте в ладоши, а если не нравится, поделитесь своими мыслями в комментариях, чтобы я мог ее улучшить.