【问题标题】:File upload with postman with pre-signed url not working使用带有预签名网址的邮递员上传文件不起作用
【发布时间】:2019-03-07 17:04:14
【问题描述】:

我正在尝试使用邮递员上传文件。我已通过单击“正文”(在邮递员中)-> 二进制-> 选择文件来附加文件。我使用 S3 上传带有预签名的网址。在url中,文件名和我在postman中选择的文件名一模一样。运行请求时,出现错误:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
    <AWSAccessKeyId>...</AWSAccessKeyId>
    <StringToSign>PUT

text/plain
1551977056
x-amz-acl:private
/wiivv-staging-private-storage/measurement/6506684788010901504/1551405460831/topLeft-2.jpeg</StringToSign>
    <SignatureProvided>...</SignatureProvided>
    <StringToSignBytes>...</StringToSignBytes>
    <RequestId>DB2FC5FE064CF49A</RequestId>
    <HostId>zbsLj7mcuXJa8D9JX1jFN1Lo+lI02/EvJreAXmPQjPezmU1sucQamXuqlGoUBzAq3nAaejx3doA=</HostId>
</Error>

但是,通过导出邮递员请求(通过单击“代码”)来获取 curl 命令,我得到:

curl -X PUT \
  '[s3-presigned-url]' \
  -H 'Postman-Token: 84700b0d-0cd2-4de5-b52c-7de39a12253e' \
  -H 'cache-control: no-cache'

并添加一个额外的文件上传选项:

curl -X PUT \
  '[s3-presigned-url]' \
  -H 'Postman-Token: 84700b0d-0cd2-4de5-b52c-7de39a12253e' \
  -H 'cache-control: no-cache'
  --upload-file ~/topLeft-2.jpeg

成功了!

总而言之,在邮递员中,它不起作用,并且在 curl 中添加了 --upload-file 选项后导出了相同的请求,它确实......

如何使请求与邮递员一起工作?

编辑 1: 看起来它与错误 https://github.com/postmanlabs/postman-app-support/issues/2521 有关,即使没有提供标题,邮递员也会自动添加 Content-Type: text/plain 标题。

编辑 2: 这是邮递员控制台的屏幕截图。看到不需要的 content-type 标头了吗? 但是,如果您切换 Pretty 输出,您将看不到该标题:

编辑 3: 使用“内容类型:多部分/表单数据”,我得到

PUT /measurement/6506684788010901504/1551405460831/topLeft-2.jpeg?AWSAccessKeyId=AKIAIKNR3HJGZI24MDTQ&Expires=1554393626&Signature=OaqaUqB2%2B3jp2AH97aWKujV3ZD8%3D&x-amz-acl=private
Content-Type: multipart/form-data; boundary=--------------------------092560820091438222667657
cache-control: no-cache
Postman-Token: e45247b4-0fc4-4adb-8e7b-effb82dc8e73
User-Agent: PostmanRuntime/7.6.1
Accept: */*
Host: wiivv-staging-private-storage.s3.amazonaws.com
accept-encoding: gzip, deflate
content-length: 199703

name=topLeft-2.jpegfilename=[object Object]

HTTP/1.1 403
status: 403
x-amz-request-id: 640967A618ABD4A0
x-amz-id-2: IVZtpEDxEEo0R7JaQWrsOi8/6UESbKH4dZNWDnwJDJBhv1ppZx56cvMPt6xT4ZJ3qWiFernsu54=
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Thu, 04 Apr 2019 15:58:34 GMT
Connection: close
Server: AmazonS3
<?xml version="1.0" encoding="UTF-8"?> <Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AKIAIKNR3HJGZI24MDTQ</AWSAccessKeyId><StringToSign>PUT multipart/form-data; boundary=--------------------------092560820091438222667657 1554393626 x-amz-acl:private /wiivv-staging-private-storage/measurement/6506684788010901504/1551405460831/topLeft-2.jpeg</StringToSign><SignatureProvided>OaqaUqB2+3jp2AH97aWKujV3ZD8=</SignatureProvided><StringToSignBytes>50 55 54 0a 0a 6d 75 6c 74 69 70 61 72 74 2f 66 6f 72 6d 2d 64 61 74 61 3b 20 62 6f 75 6e 64 61 72 79 3d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 30 39 32 35 36 30 38 32 30 30 39 31 34 33 38 32 32 32 36 36 37 36 35 37 0a 31 35 35 34 33 39 33 36 32 36 0a 78 2d 61 6d 7a 2d 61 63 6c 3a 70 72 69 76 61 74 65 0a 2f 77 69 69 76 76 2d 73 74 61 67 69 6e 67 2d 70 72 69 76 61 74 65 2d 73 74 6f 72 61 67 65 2f 6d 65 61 73 75 72 65 6d 65 6e 74 2f 36 35 30 36 36 38 34 37 38 38 30 31 30 39 30 31 35 30 34 2f 31 35 35 31 34 30 35 34 36 30 38 33 31 2f 74 6f 70 4c 65 66 74 2d 32 2e 6a 70 65 67</StringToSignBytes><RequestId>640967A618ABD4A0</RequestId><HostId>IVZtpEDxEEo0R7JaQWrsOi8/6UESbKH4dZNWDnwJDJBhv1ppZx56cvMPt6xT4ZJ3qWiFernsu54=</HostId></Error>

【问题讨论】:

    标签: curl amazon-s3 postman


    【解决方案1】:

    您在 Postman 中的错误点是正确的,或者您在第一步中缺少文件名,这就是签名不匹配错误的原因。当我没有将文件名传递给上传并“假设”我机器上的文件名将在 S3 上使用时,我遇到了这种签名不匹配的情况。事实并非如此。

    编辑

    内容类型应该是 multipart/form-data 而不是纯文本。您可以在上传文件时使用 name="filename",如下例所示。

    PUT  HTTP/1.1
    cache-control: no-cache
    Postman-Token: 98317a86-3352-48f6-bff0-e25413cb56dd
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
    
    Content-Disposition: form-data; name="status.png"; filename="/Desktop/status.png
    

    【讨论】:

    • 我会再试一次,确保没有丢失文件。
    • 你可能是对的。我没有在任何地方说明文件名。我假设通过从邮递员那里选择文件,它会使用它作为文件名。你会建议我如何传递文件名?
    • 我试过了,也没有用,我添加了原始请求和响应,如邮递员控制台中所示(编辑 3)。
    【解决方案2】:

    好吧,无论谁遇到这个问题,我都是这样解决的。在我们的应用程序逻辑中,我们现在使用给定的 application/octet-stream 类型的内容类型对 url 进行了预签名(我认为这并不重要,重要的是覆盖由邮递员桌面应用程序),我们将指定的内容类型与邮递员请求一起发送。

    let s3Param = {
      Bucket: this.bucketName,
      Key: filePath,
      Expires: bucketConfig.uploadExpireInSecond,
      ACL: bucketConfig.acl,
      ContentType: 'application/octet-stream',
    };
    
    s3.getSignedUrl('putObject', s3Param, ...);
    

    在邮递员请求标头中,我们有“Conent-Type: application/octet-stream”

    【讨论】:

      猜你喜欢
      • 2020-11-05
      • 2022-10-09
      • 1970-01-01
      • 1970-01-01
      • 2019-10-22
      • 2019-07-09
      • 2018-02-09
      • 2018-06-25
      • 2021-06-10
      相关资源
      最近更新 更多