google 云函数中的全局范围变量初始化

Global scope variable initialization in google cloud function

我想使用 Google Cloud KMS 存储密钥并在 Google Cloud Function 中使用它。首先我会加密我的密钥并将其存储在环境变量

如果我像 link 一样解密我的密钥,它 returns Promise。 当我的函数被部署和调用时,我的变量是否保证完成初始化?

我是该代码片段和 corresponding blog post 的作者。对于 post 历史,这里是 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 是一种异步语言,所以不能保证变量 usernamepassword 在函数调用之前完全初始化。在该片段中,我针对 "decrypt at function boot so each function invocation runs in constant time" 进行了优化。在您的示例中,您想要针对 "the function is fully initialized before invocation" 进行优化,这需要对代码进行一些重新组织。

一种可能的解决方案是将查找移动到调用 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}`)
}

请注意,我在这里添加了一个缓存层,因为您可能不想在每次调用该函数时都解密加密的 blob。