在 Firebase 环境变量中存储 google api 密钥

Storing the googleapi Secret Keys in Firebase Environmental Variables

问题

我想在安全位置存储 googleapis 的秘密 API 密钥。当我将来自 googleapis 的秘密 API 密钥存储为 Firebase 环境变量时,private_key 处理 与我 require("./privatekey.json"); 时相同 请参阅问题以下:

上下文

我已经从 Google 下载并解码了一个秘密 API 密钥。大多数 examples 显示在项目路径中保存解码的 JSON 文件并使用 require 将令牌拉入代码。

const SERVICE_ACCOUNT_KEY_FILE = require("./privatekey.json");  <----- This is Bad!!


const SERVICE_ACCOUNT_EMAIL = 'email@serviceaccount.com';
const jwt = new googleapis.auth.JWT(
        SERVICE_ACCOUNT_EMAIL,
        SERVICE_ACCOUNT_KEY_FILE.private_key,
        null,
        ['https://www.googleapis.com/auth/analytics.readonly']);

我使用了 firebase-clifirebase functions:config:set Firebase 环境变量。完成并重新部署后,我 运行 firebase functions:config:get 并且我看到:

 "googleapi_credentials": {
    "private_key": "-----BEGIN PRIVATE KEY-----\nMIIE  ... q0DEg==\n-----END PRIVATE KEY-----\n",

问题

当我配置 googleapis.auth.JWT() 时,我需要提供 googleapis Secret API 密钥。当我使用 require 提取密钥 API 时,请求有效。

但是,如果我尝试访问 Firebase Environmental Variable 以提供秘密 API 密钥,请求会失败。

var jwt = new googleapis.auth.JWT(
        functions.config().googleapi_credentials.client_email,
        functions.config().googleapi_credentials.private_key, <----- NOPE!
        null,
        ['https://www.googleapis.com/auth/analytics.readonly']);

调试

为了看看有什么不同,我在 firebase 函数日志视图中比较了两个标记的 console.log()。我存储在 JSON 文件和 Firebase 环境变量中的令牌在代码中看起来是一样的,也就是说,两个字符串匹配并且它们包含许多 \n(换行符)。

现在,当我查看 Firebase 函数日志 中的 console.log() returns 时,我看到了不同的标记。

console.log("JSON Private.Key", privatekey.private_key)

日志中的查看returns格式化字符串,所有\n换行,接受token

console.log("Private.Key", functions.config().googleapi_credentials.private_key)

Logs returns 一个 sting 将全部 \n 替换为 \n.,并且不接受令牌。

最后的笔记

googleapis.auth.JWT()函数可以接受一个对象作为参数吗?如果使用 Firebase 环境变量,是否需要考虑这一点?

Firebase 环境详细信息在添加斜杠时存在问题,可能会破坏 \n 个字符串。

GitHub 上有一个开放的工单,应该参考; github.com/firebase/firebase-tools/issues/371

这是我发现的 YunjorGlez 发布的黑客攻击。这对我有用。

您可以使用 .replace(/\n/g, '\n') 删除添加到 private_key.

const serviceAccount = functions.config().fireenv;

admin.initializeApp({
   credential: admin.credential.cert({
      "projectId": serviceAccount.project_id,
      "private_key": serviceAccount.private_key.replace(/\n/g, '\n'),
      "clientEmail": serviceAccount.client_email
   }),
   databaseURL: whatever,
   ...
});