Google Apps脚本上的Firebase数据库秘密

问题描述 投票:1回答:2

所以,首先,我要问这个问题,因为我希望有人承认或否认 - 对我来说是一个神话 - 即使用或不使用已弃用的firebase数据库机密。

为什么这个?好吧,在Firebase控制台的“服务帐户”选项卡中,我可以读到:

数据库机密目前已弃用,并使用旧版Firebase令牌生成器。使用Firebase Admin SDK更新源代码

但是在这个建议之下,我现在可以看到我的秘密密钥了。如果实际上不推荐使用此密钥,为什么这可能呢?

但这个故事并没有在这里结束。如果使用Google Apps脚本(even on officials)搜索教程,他们会使用已弃用的数据库密钥,但您可以阅读:

Google警告此弃用身份验证方法。实际上,您仍然可以使用此方法,但标准服务帐户更安全且值得推荐。由于数据库机密更容易使用,对于大多数用例而言,远非真正弃用和安全,这就是我们将在这里使用的内容。

再次,这怎么可能?

我想说我尝试过:

function myFunction() {
  var firebaseUrl = "https://myApp.firebaseio.com/";
  var secret = "theKey";
  var database = FirebaseApp.getDatabaseByUrl(firebaseUrl, secret);
  Logger.log(database.getData());
}

它有效,因为我可以看到数据。为什么秘密存在?这让我认为允许使用密钥,即使它已被弃用

任何意见?

firebase google-apps-script firebase-realtime-database firebase-authentication firebase-security
2个回答
1
投票

所以我had this issue整整一年半,你是对的,使用Firebase和Apps脚本的信息已经过时且具有误导性。我想通了,我正在尝试更新StackOverflow和教程中的信息。

但这个故事并没有在这里结束。如果使用Google Apps脚本(even on officials)搜索教程,他们会使用已弃用的数据库密钥,但您可以阅读此内容...

你在这里添加的这个链接实际上是一个名叫@RomainVialard的家伙的第三方网站。他的东西过去对我非常有用。虽然他的网站上的教程已经过时,但他创建的图书馆仍然运行良好,最近半年更新。


问题(服务器端) - 回答OP的问题

因此,对于服务器端部分,我使用official-ish OAuth2 Libraryservice account with a private key生成访问令牌:https://console.firebase.google.com/u/0/project/<YOUR-PROJECT-ID>/settings/serviceaccounts/adminsdk。然后我创建了一个从oauth2库中检索令牌的函数:

function getFirebaseService() {  
  return OAuth2.createService('Firebase')
      // Set the endpoint URL.
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')

      // Set the private key and issuer. I stored mine in the PropertiesService... You could just use a variable somewhere.
      .setPrivateKey(fb_PRIVATE_KEY) //Service account private key
      .setIssuer(fb_SERVICE_EMAIL) //Service account email

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getScriptProperties())

      // Set the scopes.
      .setScope('https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/firebase.database');
}

使用此代码,我可以调用getFirebaseService().getAccessToken(),它返回一个有效的“admin”或编辑级访问令牌,可以在Firebase调用中使用!我使用FirebaseApp库因为它很简单!

var service = getFirebaseService();
  if (service.hasAccess()) {
    var fb = FirebaseApp.getDatabaseByUrl(fb_URL, service.getAccessToken());
    //Success! Do what ever with Firebase!!

  } else {
    Logger.log("makeToken: " + service.getLastError());
  }

如果需要,您还可以生成客户端身份验证令牌以使用客户端:FirebaseApp.getDatabaseByUrl(fb_URL, service.getAccessToken()).createAuthToken(USER_EMAIL);


另一个常见问题(客户端)

我必须克服in my question的主要问题是Firebase Admin SDK已升级到3.x.如果你update the tutorial code to use the 3.x version一切都很棒!

// Initialize Firebase
var config = {
  apiKey: "<Web API Key>",
  authDomain: "<Project ID>.firebaseapp.com",
  databaseURL: "https://<DB URL>.firebaseio.com/"
  };

firebase.initializeApp(config);

//userRequestToken is retrieved from server-side Romain's FirebaseApp Library linked above.
firebase.auth().signInWithCustomToken(userRequestToken).catch(function(error) {
    // Handle Errors here.
    console.error("authClient: ", error.code, error.message);
  });

  return {
    uid: firebase.auth().currentUser.uid,
    metadata: {
      lastSignInTime: firebase.auth().currentUser.lastSignInTime
    }
  }; 

1
投票

好吧,既然有些用户已经对问题进行了一年多的考虑(也考虑了Chris W的回答),我使用GSApp库发布了该方法,该库也没有数据库秘密:

  1. 安装GSApp库。为此,请转到“资源”选项卡,然后单击“库”并粘贴libraryId:MJ5317VIFJyKpi9HCkXOfS0MLm9v2IJHf
  2. 创建服务帐户: 在开发人员控制台中创建一个新的API项目,或使用与您的脚本关联的API项目。 选择API和Auth - > Credentials。 点击“创建新客户ID”。 选择服务帐户并生成新的JSON密钥。 点击“创建客户端ID”。 JSON密钥将自动下载。 点击左侧菜单中的“API”。 启用您需要此服务帐户才能访问的任何API。
  3. 复制下载的JSON密钥文件的内容并将其粘贴到脚本属性中。为此,请转到文件 - >项目属性 - >脚本属性选项卡。在字段属性类型service_account(或者您想要命名它),并在值字段中粘贴JSON密钥文件的所有内容。
  4. 使用以下代码作为示例: function myFunction() { var firebaseUrl = "https://YOUR-FIREBASE-PROJECT.firebaseio.com/"; var jsonKey = JSON.parse(PropertiesService.getScriptProperties().getProperty("service_account")); var key = jsonKey.private_key; var clientEmail = jsonKey.client_email; var serverToken = new GSApp.init(key, ['https://www.googleapis.com/auth/firebase.database', 'https://www.googleapis.com/auth/userinfo.email'], clientEmail); serverToken.addUser(clientEmail).requestToken(); var token = serverToken.getToken(clientEmail).token; var dataPath = 'YOUR-FIREBASE-DATA-PATH'; var options = {}; var result = UrlFetchApp.fetch( firebaseUrl + dataPath + '.json' + '?access_token=' + token, options).getContentText(); var data = JSON.parse(result); var keys = Object.keys(data); var sheetRow = []; var entryKeys; for (index in keys) { sheetRow = []; entryKeys = Object.keys(data[keys[index]]) for (i in entryKeys) { Logger.log(entryKeys[i]); } } }

您从firebase获取数据作为json对象,这意味着您需要手动浏览所有对象的属性(forEach, map, for ... of)

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.