5
votes

getSignedURL () dans Google Cloud Function génère un lien qui fonctionne pendant plusieurs jours, puis renvoie "SignatureDoesNotMatch"

Les liens de téléchargement de My Firebase Storage getSignedUrl () fonctionnent pendant quelques jours, puis cessent de fonctionner. Le message d'erreur est

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)
            }
          });
        });
      });
    });
  }

L'été dernier, il y a eu un long discussion de ceci sur GitHub mais je ne vois pas de solution trouvée.

Je pense utiliser getDownloadURL () depuis le front-end au lieu d'utiliser getSignedUrl () depuis le back-end. Est-ce que getDownloadURL () est moins sécurisé que getSignedUrl()?

Voici mon code, qui est principalement copié à partir du documentation :

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

p >


3 commentaires

Avez-vous essayé d'utiliser un compte de service explicite? Le bogue auquel vous créez un lien le répertorie comme une solution.


Oui, serviceAccount est défini sur un fichier json local, puis admin.initializeApp appelle le serviceAccount. J'appelle admin.firestore et admin.auth, mais je n'appelle jamais admin.storage, comme vous pouvez le voir dans le code ci-dessus. Au lieu de cela, je fais "const storage = new Storage ();", copié de la documentation Google. Peut-être devrais-je utiliser admin.storage au lieu de "new Storage ()"? Je ne sais pas d'où "new Storage ()" obtient un compte de service.


OK, je suis passé de "const storage = new Storage ();" à "const storage = admin.storage ();". Cela fonctionne, demandez-moi dans un mois si les URL de téléchargement signées fonctionnent toujours! Et ce matin, j'ai refactorisé mon front-end pour utiliser getDownloadURL () au lieu de compter sur le back-end pour fournir des URL signées. À la lecture de la discussion sur GitHub, il semble que les URL signées étaient destinées à une utilisation à court terme. La version "v4" ne peut pas avoir de date d'expiration au-delà d'une semaine! Et Google effectue une rotation des clés de service chaque semaine. Je préfère les URL signées, car getDownloadURL () a ajouté des centaines de lignes de code complexe à mon application.


3 Réponses :


5
votes

La durée maximale d'une URL signée Google Cloud Storage est de 7 jours. Mais cela peut aussi être plus court. Jamais plus. Je suppose que le stockage Firebase a la même limite.


3 commentaires

J'hésite à vous donner la coche verte car ce n'est pas la réponse que je veux, mais il y a toutes les raisons de vous croire. La documentation ( cloud.google.com/nodejs/docs /reference/storage/2.3.x/... ) dit que "expire" est "un horodatage quand ce lien expirera", sans rien dire sur une limite de sept jours. Les exemples de documentation ont "expires: '03 -17-2025 '", ce qui implique que vous pouvez définir la date d'expiration des années dans le futur. Mais peu importe ce que je fais, les URL de téléchargement expirent dans sept jours.


Existe-t-il un moyen d'obtenir une URL de téléchargement permanente à partir d'une fonction Google Cloud? Je sais comment utiliser getDownloadURL () depuis le navigateur, mais je ne parviens pas à le faire fonctionner dans une fonction cloud. getDownloadURL () n'est pas une fonction Node. Il me semble étrange que je puisse obtenir une URL de téléchargement permanente à partir du navigateur et une URL de téléchargement temporaire à partir de la fonction Cloud. Cela ne devrait-il pas être l'inverse? Les navigateurs sont transitoires, personne ne gardera son navigateur ouvert pendant une semaine. Mais lorsque je télécharge des fichiers à partir d'une fonction cloud, c'est permanent, et l'URL de téléchargement doit être permanente,


Si vous activez l'accès public sur votre objet dans Cloud Storage, vous pouvez utiliser une URL directe vers cet objet. Tout le monde avec cette URL peut télécharger l'objet.



0
votes

J'ai écrit une longue réponse à cette question: [ Obtenir l'URL de téléchargement à partir du fichier téléchargé avec Cloud Functions pour Firebase . Cette question peut être marquée comme dupliquée.


  [1]: https://stackoverflow.com/questions/42956250/get-download-url-from-file-uploaded-with-cloud-functions-for-firebase


3 commentaires

Dix jours plus tard, les URL de téléchargement signées sont mortes. Problème non résolu!


Thomas David Kehoe - avez-vous déjà trouvé une solution à cela? Ce problème me rend dingue depuis très longtemps.


@barrylachapelle, j'ai écrit une longue réponse ici: stackoverflow.com/questions/42956250/… Je teste une autre idée suggérée par quelqu'un (en utilisant uuidv2 au lieu de uuidv4), demandez-moi dans une semaine si cela a fonctionné!



1
votes

L'URL prédéfinie expirera à la date que vous indiquez dans le champ expires .

Cependant, le problème que vous rencontrez ici est que les clés KMS du SDK d'administration sont alternées tous les 7 jours. Ainsi, si vous créez l'URL pré-signée à l'aide de la bibliothèque de stockage () provisionnée automatiquement, une fois que les clés ont pivoté, votre URL pré-signée ne sera plus valide (car la clé utilisée pour la signer n'est plus valide). Ainsi, votre URL sera valide pendant une durée inférieure ou égale à 7 jours en fonction de l'âge de la clé.

À la place, vous devez ne pas utiliser le SDK d'administration et utiliser à la place le Google Cloud Storage module npm et initialisez-le avec un compte de service json.

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

ou

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


0 commentaires