Reputation: 10930
My Firebase Storage getSignedUrl()
download links work for a few days, then stop working. The error message is
SignatureDoesNotMatch
The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.
Last summer there was a long discussion of this on GitHub but I don't see that a solution was reached.
I'm thinking of using getDownloadURL()
from the front end instead of using getSignedUrl()
from the back end. Is getDownloadURL()
less secure then getSignedUrl()
?
Here's my code, which is mostly copied from the 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)
}
});
});
});
});
}
Upvotes: 10
Views: 18447
Reputation: 153
The presigned URL will expire at the date you provide with the expires
field.
However, the issue you are seeing here is that KMS keys for the admin SDK are rotated every 7 days. So if you create the presignedURL using the auto-provisioned storage() library, once the keys rotate your presigned URL will no longer be valid (because the key used to sign it is no longer valid). So your URL will be valid for less than or equal to 7 days depending on the age of the key.
Instead you need to not use the admin SDK and instead use the Google Cloud Storage npm module and initialize it with a service account json.
const storage = new Storage({keyFilename: "key.json"});
or
`const storage = new Storage({credential: require("key.json")});
Upvotes: 8
Reputation: 10930
I've written a long answer to this question: [Get Download URL from file uploaded with Cloud Functions for Firebase. This question can be marked as a duplicate.
[1]: https://stackoverflow.com/questions/42956250/get-download-url-from-file-uploaded-with-cloud-functions-for-firebase
Upvotes: 0
Reputation: 5228
The maximum duration of a Google Cloud Storage Signed URL is 7 days. But it can also be shorter. Never longer. I guess the Firebase Storage has the same limit.
Upvotes: 7