Google Cloud Function中的getSignedURL()会生成可工作几天的链接,然后返回“ SignatureDoesNotMatch”

时间:2019-03-27 23:32:41

标签: node.js firebase google-cloud-storage firebase-storage

我的Firebase存储getSignedUrl()下载链接会工作几天,然后停止工作。错误消息是

SignatureDoesNotMatch
The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.

去年夏天,在GitHub上有很长的discussion,但我看不出有解决方案。

我正在考虑从前端使用getDownloadURL()而不是从后端使用getSignedUrl()getDownloadURL()的安全性是否比getSignedUrl()小?

这是我的代码,大部分是从documentation复制的:

let audioType = 'mp3';
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const bucket = storage.bucket('my-app.appspot.com');
var file = bucket.file('Audio/' + longLanguage + '/' + pronunciation + '/' + wordFileType);

  // Firebase Storage file options
  var options = {
    metadata: {
      contentType: 'audio/' + audioType,
      metadata: {
        audioType: audioType,
        longAccent: 'United_States',
        shortAccent: 'US',
        longLanguage: 'English',
        shortLanguage: 'en',
        source: 'Oxford Dictionaries',
        word: word
      }
    }
  };

  const config = {
    action: 'read',
    expires: '03-17-2025',
    content_type: 'audio/mp3'
  };

  function oedPromise() {
    return new Promise(function(resolve, reject) {
      http.get(oedAudioURL, function(response) {
        response.pipe(file.createWriteStream(options))
        .on('error', function(error) {
          console.error(error);
          reject(error);
        })
        .on('finish', function() {
          file.getSignedUrl(config, function(err, url) {
            if (err) {
              console.error(err);
              return;
            } else {
              resolve(url)
            }
          });
        });
      });
    });
  }

3 个答案:

答案 0 :(得分:1)

Google Cloud Storage签名URL的最长持续时间为7天。但它也可以更短。再也不会了。我猜Firebase存储有相同的限制。

答案 1 :(得分:1)

预签名URL将在您使用expires字段提供的日期过期。

但是,您在这里看到的问题是admin SDK的KMS密钥每7天轮换一次。因此,如果使用自动配置的storage()库创建presignedURL,则一旦密钥旋转,您的预签名URL将不再有效(因为用于签名的密钥不再有效)。因此,根据密钥的使用期限,您的URL有效期将少于或等于7天。

相反,您无需使用管理SDK,而可以使用Google Cloud Storage npm module并使用服务帐户json对其进行初始化。

const storage = new Storage({keyFilename: "key.json"});

`const storage = new Storage({credential:require(“ key.json”)});

答案 2 :(得分:0)

我想我已经找到问题了。该错误位于documentation

const storage = new Storage();

根据道格·史蒂文森的answer,另一个问题应该是

const storage = new Storage({
  projectId: projectId,
});

projectId链接您的凭据。没有projectId,您的签名URL将不会被签名。令人困惑的是,没有您的projectId,已签名的URL可以使用三到七天(无论您在expires属性中指定的日期如何)。

两周后问我下载网址是否仍然有效!