getSignedUrl gibt „SigningError: Fehler vom Metadatenserver“ aus.

getSignedUrl gibt „SigningError: Fehler vom Metadatenserver“ aus.

Ich verwende Google Cloud Functions mit einem HTTP-Trigger, um einen Endpunkt für einen API-Aufruf zu erstellen. Dieser Endpunkt verwendet die getSignedUrlFunktion aus dem Cloud Storage-Paket. Ich wollte eine signierte URL zurückgeben, damit der Client zu dieser URL eine Datei hochladen kann PUT.

Ich habe mit dieser API ein inkonsistentes Verhalten. Manchmal bekomme ich von der Funktion eine URL zurück. Dann habe ich versucht, den Bucket-Namen zu aktualisieren und erhalte diesen Fehler:

{ SigningError: Failure from metadata server.
at /user_code/node_modules/@google-cloud/storage/src/file.js:1715:16
at getCredentials (/user_code/node_modules/@google-cloud/storage/node_modules/google-auto-auth/index.js:264:9)
at googleAuthClient.getCredentials (/user_code/node_modules/@google-cloud/storage/node_modules/google-auto-auth/index.js:148:11)
at process._tickDomainCallback (internal/process/next_tick.js:135:7) message: 'Failure from metadata server.' }

Wenn ich den Bucket-Namen wieder ändere, wird mir immer noch dieser Fehler angezeigt. Ich habe verschiedene Dinge ausprobiert, z. B. die Bereitstellung über das Terminal. Dabei trat der gleiche Fehler auf. Ich habe die Funktion auch mit dem Browser erstellt und das funktionierte. Nachdem ich versucht hatte, den Bucket-Namen zu aktualisieren, funktionierte es nicht mehr.

Nach einigem Googeln bin ich zu dem Schluss gekommen, dass es sich um ein Berechtigungs- oder ACL-Problem handelt, aber ich bin mir nicht sicher, wie ich das bestätigen kann. In der Dokumentation steht, dass Funktionen über ein <YOUR_PROJECT_ID>@appspot.gserviceaccount.comDienstkonto ausgeführt werden, was ich auf der Registerkarte „Allgemein“ der Funktion bestätigen kann. Ich kann in IAM sehen, dass dieses Dienstkonto über das verfügt Service Account Token Creator, das besagt:

Dienstkonten imitieren (OAuth2-Zugriffstoken erstellen, Blobs oder JWTs signieren usw.).

In der Dokumentation getSignedUrlheißt es:

In diesen Umgebungen rufen wir die signBlob-API auf, um eine signierte URL zu erstellen. Diese API erfordert entweder diehttps://www.googleapis.com/auth/iamoderhttps://www.googleapis.com/auth/cloud-platformUmfang, stellen Sie also sicher, dass sie aktiviert sind.

Ich denke, das sollte ausreichen, damit es funktioniert. Ich weiß nicht, wie ich explizit nach Bereichen suchen kann.

sign-blobDas einzige, was ich sonst noch versucht habe, ist , es vom Terminal aus auszuführen . Ich habe Folgendes ausgeführt:

gcloud iam service-accounts sign-blob --iam-account=<my-project-id>@appspot.gserviceaccount.com input.file output.file

und ich erhalte diesen Fehler zurück:

FEHLER: (gcloud.iam.service-accounts.sign-blob) PERMISSION_DENIED: Die Berechtigung iam.serviceAccounts.signBlob ist erforderlich, um diesen Vorgang für Dienstkontoprojekte/-/serviceAccounts/ auszuführen.[email geschützt].

Ich weiß nicht, wie ich überprüfen kann, ob mein Dienstkonto über diese Berechtigung verfügt. Ich habe versucht, in IAM auf der Website, im gcloudTerminalprogramm und in den für meine Buckets festgelegten Berechtigungen danach zu suchen.

Hier ist der Code für meine Funktion:

const storage = require('@google-cloud/storage')();

exports.getSignedUrl = (req, res) => {

    if(req.method === 'POST') {

        // Perform any authorization checks here to assert
        // that the end user is authorized to upload.

        const myBucket = storage.bucket('my-bucket-name');
        const myFile = myBucket.file(req.body.filename);
        const contentType = req.body.contentType;

        // This link should only last 5 minutes
        const expiresAtMs = Date.now() + 300000;
        const config = {
            action: 'write',
            expires: expiresAtMs,
            contentType: contentType
        };

        myFile.getSignedUrl(config, function(err, url) {
            if (err) {
                console.error(err);
                res.status(500).end();
                return;
            }
            res.send(url);
        });
    } else {
        res.status(405).end();
    }
}

Hat das schon mal jemand gesehen oder weiß jemand, warum das passiert? Oder wissen Sie, wie ich überprüfen kann, ob mein Dienstkonto diese Berechtigungen oder Bereiche hat? Ich habe das Gefühl, dass dies ein Fehler in GCP sein könnte, aber wahrscheinlich übersehe ich etwas. Ich stecke schon seit einiger Zeit fest und wäre für jede Hilfe dankbar, die Sie mir geben können!

Antwort1

Ich habe das Problem gelöst, indem ich meinem Dienstkonto „App Engine-Standarddienstkonto“ die Rolle „Cloud Functions Service Agent“ hinzugefügt habe.

Gehe zu:https://console.cloud.google.com/iam-admin/iam

Suche nach „Cloud Functions Service Agent“
Rollen verwalten

Ich wurde im Kommentar von @rscotten anhand von Bildschirmausschnitten angeleitet:https://github.com/googleapis/nodejs-storage/issues/150

Antwort2

Nach einigem Herumprobieren fand ich heraus, dass diese @google-cloud/storageVersion 1.6.0dieses Verhalten aufwies. Ich führte ein Downgrade durch 1.5.2und es funktionierte.

Ich habe hierfür ein GitHub-Problem eröffnet:https://github.com/googleapis/nodejs-storage/issues/150

verwandte Informationen