You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将curl输出直接上传至Azure Storage?解决认证失败问题

直接将文件从第三方服务管道上传至Azure Storage失败,求替代方案

现有可正常工作的本地下载脚本

我通过以下bash脚本能成功从第三方服务下载文件到本地:

for secao in $tipo_dou;
do
    download="curl -k --silent -fL -b cookies.iakim 'https://inlabs.in.gov.br/index.php?p=$ano-$mes-$dia&dl=$ano-$mes-$dia-$secao.zip' -H 'origem: 736372697074' -o" 
    echo $download > $ano-$mes-$dia-$secao.sh
    sh $ano-$mes-$dia-$secao.sh
    rm -rf $ano-$mes-$dia-$secao.sh
done

尝试管道上传至Azure Storage的脚本(认证失败)

我尝试通过管道将下载的文件直接上传到Azure Storage,但遇到认证错误,脚本如下:

filename=$ano-$mes-$dia&dl=$ano-$mes-$dia-$secao.zip
for secao in $tipo_dou;
do
    download="curl -k --silent -fL -b cookies.iakim 'https://inlabs.in.gov.br/index.php?p=$ano-$mes-$dia&dl=$ano-$mes-$dia-$secao.zip' -H 'origem: 736372697074' 
                 |
                curl -X PUT -T - -H x-ms-blob-type:BlockBlob 'https://server.blob.core.windows.net/ape/filename?st=2023-01-25T18:41:00Z&se=2025-12-01T02:41:00Z&spr=https&sv=2021-06-08&sr=c&sig=SIGNATUREID'" 
    echo $download > $ano-$mes-$dia-$secao.sh
    sh $ano-$mes-$dia-$secao.sh
    rm -rf $ano-$mes-$dia-$secao.sh
done

遇到的错误信息

<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:6b17fae3-601e-0065-5483-31ec49000000
Time:2023-01-26T12:43:31.1912380Z</Message>

用于执行脚本的Node.js代码

我通过Node.js的child_process执行上述bash脚本:

const { exec } = require('child_process');
const fs = require('fs');
const zlib = require('zlib');

const directoryFiles = fs.readdirSync('.');

const download = exec('sh xml-downloader.sh', (error, stdout, stderr ) => {
    console.log('stdout: ', stdout);
    console.log('stderr: ', stderr);
    if (error !== null) {
        console.log('exec error: ', error);
    }
})

可行的替代实现方法

方法1:使用Azure CLI替代curl上传

Azure CLI的az storage blob upload支持从标准输入读取数据,无需手动处理签名,可靠性更高。修改bash脚本如下:

for secao in $tipo_dou; do
  blob_name="$ano-$mes-$dia-$secao.zip"
  curl -k --silent -fL -b cookies.iakim "https://inlabs.in.gov.br/index.php?p=$ano-$mes-$dia&dl=$ano-$mes-$dia-$secao.zip" -H 'origem: 736372697074' \
    | az storage blob upload \
      --container-name ape \
      --name "$blob_name" \
      --account-name server \
      --type blockblob \
      --file -
done

注意:需先通过az login完成认证,或设置环境变量AZURE_STORAGE_ACCOUNT和AZURE_STORAGE_KEY/AZURE_STORAGE_SAS_TOKEN跳过登录步骤。

方法2:在Node.js中直接处理下载与上传

用Node.js的HTTP客户端(如axios)获取文件流,再通过Azure Storage SDK直接上传,全程在Node.js环境内处理,更可控:

const { BlobServiceClient } = require('@azure/storage-blob');
const axios = require('axios');
const https = require('https');
const fs = require('fs');

// 配置Azure Storage连接
const connectionString = "你的Azure存储账户连接字符串";
const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = blobServiceClient.getContainerClient('ape');

// 替换为实际参数
const ano = '2023';
const mes = '01';
const dia = '26';
const tipo_dou = ['secao1', 'secao2']; // 替换为实际的secao列表

// 读取cookies文件
const cookies = fs.readFileSync('cookies.iakim', 'utf8').trim();

async function downloadAndUpload(secao) {
  const blobName = `${ano}-${mes}-${dia}-${secao}.zip`;
  const downloadUrl = `https://inlabs.in.gov.br/index.php?p=${ano}-${mes}-${dia}&dl=${ano}-${mes}-${dia}-${secao}.zip`;

  try {
    // 获取下载流(对应curl的-k参数,禁用证书验证)
    const response = await axios.get(downloadUrl, {
      responseType: 'stream',
      headers: {
        'origem': '736372697074',
        'Cookie': cookies
      },
      httpsAgent: new https.Agent({ rejectUnauthorized: false })
    });

    // 上传到Azure Storage
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);
    await blockBlobClient.uploadStream(response.data);
    console.log(`✅ 成功上传 ${blobName}`);
  } catch (error) {
    console.error(`❌ 上传 ${blobName} 失败:`, error.message);
  }
}

// 批量执行下载上传
(async () => {
  for (const secao of tipo_dou) {
    await downloadAndUpload(secao);
  }
})();

说明:需先安装依赖包:npm install axios @azure/storage-blob

方法3:修复原curl管道的签名问题

原脚本中SAS URL使用固定的filename而非实际blob名称,导致签名验证失败。修改脚本,将SAS URL中的文件名替换为实际的blob名称:

for secao in $tipo_dou; do
  blob_name="$ano-$mes-$dia-$secao.zip"
  # 确保SAS URL针对容器(sr=c),或为每个blob生成对应SAS
  sas_url="https://server.blob.core.windows.net/ape/${blob_name}?st=2023-01-25T18:41:00Z&se=2025-12-01T02:41:00Z&spr=https&sv=2021-06-08&sr=c&sig=SIGNATUREID"
  
  curl -k --silent -fL -b cookies.iakim "https://inlabs.in.gov.br/index.php?p=$ano-$mes-$dia&dl=$ano-$mes-$dia-$secao.zip" -H 'origem: 736372697074' \
    | curl -X PUT -T - -H "x-ms-blob-type:BlockBlob" "$sas_url"
done

注意:若SAS是针对单个blob生成的,需为每个blob单独生成SAS URL;若为容器级SAS(sr=c),则可复用同一SAS URL上传任意blob。


内容的提问来源于stack exchange,提问作者Fabio Faria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:20:40