getSignedUrl fornecendo "SigningError: Falha no servidor de metadados"

getSignedUrl fornecendo "SigningError: Falha no servidor de metadados"

Estou usando o Google Cloud Functions com um gatilho HTTP para criar um endpoint para uma chamada de API. Este endpoint usa a getSignedUrlfunção do pacote Cloud Storage. Eu queria retornar um URL assinado para que o cliente pudesse PUTacessar esse URL para fazer upload de um arquivo.

Estou tendo um comportamento inconsistente com esta API. Às vezes, recebo de volta um URL da função. Tentei atualizar o nome do bucket e recebi este erro:

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

Se eu alterar o nome do bucket novamente, ainda vejo esse erro. Eu tentei coisas diferentes, como implantar a partir do terminal. Isso me deu o mesmo erro. Também criei a função com o navegador e começou a funcionar. Depois de tentar atualizar o nome do bucket, ele parou de funcionar.

Pesquisando no Google, acho que se trata de um problema de permissão ou ACL, mas não sei como confirmá-lo. A documentação diz que as funções são executadas usando <YOUR_PROJECT_ID>@appspot.gserviceaccount.comconta de serviço, o que posso confirmar na aba geral da função. Posso ver no IAM que esta conta de serviço tem o Service Account Token Creator, que diz:

Representar contas de serviço (criar tokens de acesso OAuth2, assinar blobs ou JWTs, etc.).

A documentação para getSignedUrldiz:

Nesses ambientes, chamamos a API signBlob para criar um URL assinado. Essa API requer ohttps://www.googleapis.com/auth/iamouhttps://www.googleapis.com/auth/cloud-platformescopo, portanto, certifique-se de que eles estejam ativados.

Eu sinto que isso deve ser suficiente para que funcione. Não sei como verificar explicitamente os escopos.

A única outra coisa que tentei foi executar sign-bloba partir do terminal. Eu corri isso:

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

e recebo de volta este erro:

ERRO: (gcloud.iam.service-accounts.sign-blob) PERMISSION_DENIED: a permissão iam.serviceAccounts.signBlob é necessária para executar esta operação em projetos de conta de serviço/-/serviceAccounts/[e-mail protegido].

Não sei como verificar se minha conta de serviço tem essa permissão. Tentei procurá-lo no IAM no site, no gcloudprograma de terminal e nas permissões definidas em meus buckets.

Aqui está o código da minha função:

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

Alguém já viu isso antes ou sabe por que isso está acontecendo? Ou você sabe como posso verificar se minha conta de serviço tem essas permissões ou escopos? Sinto que isso pode ser um bug no GCP, mas é provável que esteja faltando alguma coisa. Estou preso nisso há um tempo e agradeceria qualquer ajuda que você possa ter!

Responder1

Resolvi isso adicionando a função "Agente de serviço do Cloud Functions" à minha conta de serviço "Conta de serviço padrão do App Engine".

Vá para:https://console.cloud.google.com/iam-admin/iam

encontre "Agente de serviço do Cloud Functions"
gerenciar funções

Fui guiado por clipes de tela no comentário de @rscotten:https://github.com/googleapis/nodejs-storage/issues/150

Responder2

Depois de algumas tentativas e erros, descobri que aquela @google-cloud/storageversão 1.6.0estava me causando esse comportamento. Fiz o downgrade para 1.5.2e começou a funcionar.

Abri um problema no GitHub para isso:https://github.com/googleapis/nodejs-storage/issues/150

informação relacionada