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

时间:2017-09-07 18:31:07

标签: firebase google-apps-script firebase-realtime-database firebase-authentication firebase-security

所以,首先,我问的是这个问题,因为我希望有人承认或否认 - 对我来说是一个神话 - 关于使用或不使用 弃用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());
}

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

有什么意见吗?

2 个答案:

答案 0 :(得分:1)

因此,我had this issue一年半后 ,您是正确的,在那里将Firebase与Apps Script一起使用的信息已经过时,误导。我发现了这个问题,并正在尝试更新StackOverflow和教程中的信息。

  

但是这个故事并没有到此结束。如果使用Google Apps脚本(even on officials)搜索教程,它们将使用不建议使用的数据库密钥,但是您可以阅读......

您在此处添加的此链接实际上是一个名为@RomainVialard的家伙实际上是第三方网站。过去,他的东西对我非常有用。虽然他网站上的教程已经过时,但他创建的库仍然运行良好,并且最近更新了。


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

因此对于服务器端,我使用official-ish OAuth2 Libraryservice account with a private keyhttps://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(),它返回可以在Firebase调用中使用的 valid 'admin'或 Editor级访问令牌 !我使用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 :(得分:1)

好吧,现在,有些用户对这个问题感兴趣-一年多以后-(还请考虑 Chris W 的回答),我使用GSApp库发布方法,该方法也可以在没有 databse秘密 的情况下工作:

  1. 安装 GSApp 库。为此,请转到“资源”标签,然后单击“库”并粘贴库ID: MJ5317VIFJyKpi9HCkXOfS0MLm9v2IJHf

  2. 创建服务帐户:

    • 在开发人员控制台中创建一个新的 API项目,或使用与您的脚本相关联的一个项目。
    • 选择 API和身份验证-> 凭据
    • 点击“创建新客户ID”
    • 选择服务帐户并生成新的JSON密钥。
    • 点击“创建客户ID” 。 JSON密钥将自动下载。
    • 点击左侧菜单中的“ API”
    • 启用您需要此服务帐户访问的所有API。
  3. 复制下载的 JSON密钥文件的内容,并将其粘贴到您的脚本属性中。为此,请转到文件-> 项目属性-> 脚本属性选项卡。在 Property 字段中键入service_account(或者您要为其命名),然后在 Value 字段中粘贴所有内容 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)浏览对象的所有属性。