getSignedUrl muestra "SigningError: error del servidor de metadatos"

getSignedUrl muestra "SigningError: error del servidor de metadatos"

Estoy usando Google Cloud Functions con un activador HTTP para crear un punto final para una llamada API. Este punto final utiliza la getSignedUrlfunción del paquete Cloud Storage. Quería devolver una URL firmada para que el cliente pueda acceder PUTa esa URL para cargar un archivo.

Tengo un comportamiento inconsistente con esta API. A veces obtengo una URL de la función. Luego intenté actualizar el nombre del depósito y aparece este error:

{ 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.' }

Si vuelvo a cambiar el nombre del depósito, sigo viendo este error. Probé diferentes cosas, como implementar desde la terminal. Eso me dio el mismo error. También creé la función con el navegador y empezó a funcionar. Después de intentar actualizar el nombre del depósito, dejó de funcionar.

Al buscar en Google, creo que se trata de un problema de permiso o de ACL, pero no estoy seguro de cómo confirmarlo. La documentación dice que las funciones se ejecutan usando <YOUR_PROJECT_ID>@appspot.gserviceaccount.comla cuenta de servicio, lo cual puedo confirmar en la pestaña general de la función. Puedo ver en IAM que esta cuenta de servicio tiene el Service Account Token Creatorque dice:

Suplantar cuentas de servicio (crear tokens de acceso OAuth2, firmar blobs o JWT, etc.).

La documentación para getSignedUrldice:

En esos entornos, llamamos a la API signBlob para crear una URL firmada. Esa API requiere elhttps://www.googleapis.com/auth/iamohttps://www.googleapis.com/auth/cloud-platformalcance, así que asegúrese de que estén habilitados.

Siento que esto debería ser suficiente para que funcione. No sé cómo comprobar explícitamente los alcances.

La única otra cosa que he intentado es ejecutar sign-blobdesde la terminal. Ejecuté esto:

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

y me sale este error:

ERROR: (gcloud.iam.service-accounts.sign-blob) PERMISSION_DENIED: Se requiere permiso iam.serviceAccounts.signBlob para realizar esta operación en proyectos de cuentas de servicio/-/serviceAccounts/[correo electrónico protegido].

No sé cómo comprobar que mi cuenta de servicio tenga este permiso. Intenté buscarlo en IAM en el sitio web, el gcloudprograma de terminal y los permisos establecidos en mis depósitos.

Aquí está el código para mi función:

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

¿Alguien ha visto esto antes o sabe por qué sucede esto? ¿O sabes cómo puedo verificar si mi cuenta de servicio tiene estos permisos o alcances? Siento que esto puede ser un error en GCP, pero es probable que me esté perdiendo algo. ¡He estado atrapado en esto por un tiempo y agradecería cualquier ayuda que pueda tener!

Respuesta1

Lo resolví agregando la función "Agente de servicio de Cloud Functions" a mi cuenta de servicio "Cuenta de servicio predeterminada de App Engine".

Ir a:https://console.cloud.google.com/iam-admin/iam

busque "Agente de servicios de Cloud Functions"
gestionar roles

Me guiaron con clips de pantalla en el comentario de @rcotten:https://github.com/googleapis/nodejs-storage/issues/150

Respuesta2

Después de algunas pruebas y errores, descubrí que la @google-cloud/storageversión 1.6.0me estaba dando este comportamiento. Bajé de categoría 1.5.2y empezó a funcionar.

Abrí un problema de GitHub para esto:https://github.com/googleapis/nodejs-storage/issues/150

información relacionada