Estoy usando Google Cloud Functions con un activador HTTP para crear un punto final para una llamada API. Este punto final utiliza la getSignedUrl
función del paquete Cloud Storage. Quería devolver una URL firmada para que el cliente pueda acceder PUT
a 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.com
la 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 Creator
que dice:
Suplantar cuentas de servicio (crear tokens de acceso OAuth2, firmar blobs o JWT, etc.).
La documentación para getSignedUrl
dice:
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-blob
desde 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 gcloud
programa 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/storage
versión 1.6.0
me estaba dando este comportamiento. Bajé de categoría 1.5.2
y empezó a funcionar.
Abrí un problema de GitHub para esto:https://github.com/googleapis/nodejs-storage/issues/150