Инициализация глобальной области видимости в облачной функции Google
Я хочу сохранить секретный ключ с помощью Google Cloud KMS и использовать его в Google Cloud Function. Сначала я зашифрую свой ключ и сохраню его в переменной окружения
Если я расшифрую свой секретный ключ, такой как ссылка, он вернет Обещание. Гарантируется ли, что моя переменная завершает инициализацию, когда моя функция развернута и вызвана?
1 ответ
Я являюсь автором этого фрагмента кода и соответствующего сообщения в блоге. Для истории постов вот полный фрагмент, на который ссылается OP:
const cryptoKeyID = process.env.KMS_CRYPTO_KEY_ID;
const kms = require('@google-cloud/kms');
const client = new kms.v1.KeyManagementServiceClient();
let username;
client.decrypt({
name: cryptoKeyID,
ciphertext: process.env.DB_USER,
}).then(res => {
username = res[0].plaintext.toString().trim();
}).catch(err => {
console.error(err);
});
let password;
client.decrypt({
name: cryptoKeyID,
ciphertext: process.env.DB_PASS,
}).then(res => {
password = res[0].plaintext.toString().trim();
}).catch(err => {
console.error(err);
});
exports.F = (req, res) => {
res.send(`${username}:${password}`)
}
Поскольку Node является асинхронным языком, нет гарантии, что переменные username
а также password
полностью инициализируются перед вызовом функции как написано. В этом фрагменте я оптимизирован для "расшифровки при загрузке функции, поэтому каждый вызов функции выполняется в постоянное время". В вашем примере вы хотите оптимизировать для "функция полностью инициализируется перед вызовом", что требует некоторой реорганизации кода.
Одним из возможных решений является перемещение поиска в функцию Node, которая вызывается при вызове функции GCF. Например:
const cryptoKeyID = process.env.KMS_CRYPTO_KEY_ID;
const kms = require('@google-cloud/kms');
const client = new kms.v1.KeyManagementServiceClient();
let cache = {};
const decrypt = async (ciphertext) => {
if (!cache[ciphertext]) {
const [result] = await client.decrypt({
name: cryptoKeyID,
ciphertext: ciphertext,
});
cache[ciphertext] = result.plaintext;
}
return cache[ciphertext];
}
exports.F = async (req, res) => {
const username = await decrypt(process.env.DB_USER);
const password = await decrypt(process.env.DB_PASS);
res.send(`${username}:${password}`)
}
Обратите внимание, что я добавил слой кэширования, так как вы, вероятно, не хотите расшифровывать зашифрованный большой двоичный объект при каждом вызове функции.