使用邮递员调用 S3 预签名 URL

use*_*161 3 amazon-s3 amazon-web-services pre-signed-url postman

我正在尝试按照文档 ( https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html )中的描述使用预先签名的 URL 进行上传,我可以检索预先签名的 URL,但是当我尝试在 Postman 中执行 PUT,收到以下错误:

<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
Run Code Online (Sandbox Code Playgroud)

显然,我的 put 调用的结构方式与 AWS 计算签名的方式不匹配。我找不到很多关于这个看跌调用需要什么的信息。

我试图将 Content-Type 的标头修改为 multipart/form-data 和 application/octet-stream。我还尝试在 postman 中取消勾选 headers 部分,并依赖正文类型来选择文件的表单数据和二进制设置。表单数据设置导致以下添加到调用中:

内容配置:表单数据;name="thefiletosend.txt"; 文件名="thefiletosend.txt

此外,我注意到邮递员包括它所谓的“临时标题”,如下所示:

主机:s3.amazonaws.com Content-Type:text/plain User-Agent:PostmanRuntime/7.13.0 Accept:/ Cache-Control:no-cache Postman-Token:e11d1ef0-8156-4ca7-9317-9f4d22daf6c5,2135bc0e-128 -4438-bb8e-b21d31dc36db 主机:s3.amazonaws.com 接受编码:gzip,放气内容长度:14 连接:保持活动缓存控制:无缓存

Content-Type 标头可能是问题之一,但我不确定如何在邮递员中排除这些“临时标头”。

我在 lambda 中生成预先签名的 URL,如下所示:

    public string FunctionHandler(Input input, ILambdaContext context)
    { 
        _logger = context.Logger;
        _key = input.key;
        _bucketname = input.bucketname;

        string signedURL = _s3Client.GetPreSignedURL(new GetPreSignedUrlRequest()
        {
            Verb = HttpVerb.PUT ,
            Protocol = Protocol.HTTPS,
            BucketName = _bucketname,
            Key = _key,
            Expires = DateTime.Now.AddMinutes(5)
        });

        returnObj returnVal = new returnObj() { url = signedURL };

        return JsonConvert.SerializeObject(returnVal);

    }
Run Code Online (Sandbox Code Playgroud)

小智 11

你的预签名网址应该是这样的 https://bucket-name.s3.region.amazonaws.com/folder/filename.jpg?AWSAccessKeyId=XXX&Content-Type=image%2Fjpeg&Expires=XXX&Signature=XXX

您可以通过邮递员上传到 S3

  1. 将上面的 url 设置为端点
  2. 选择PUT请求,
  3. Body-> binary->Select file

  • 谢谢!我将该文件添加为表单数据参数,这导致图像文件损坏。 (2认同)

moj*_*ken 7

我能够使用 POST 请求在 Postman 中完成这项工作。以下是对我有用的细节。当我调用我的 lambda 来获取预先签名的 URL 时,这里是返回的 json(在我屏蔽了敏感和特定于应用程序的信息之后):

{
    "attachmentName": "MySecondAttachment.docx",
    "url": "https://my-s3-bucket.s3.amazonaws.com/",
    "fields": {
        "acl": "public-read",
        "Content-Type": "multipart/form-data",
        "key": "attachment-upload/R271645/65397746_MySecondAttachment.docx",
        "x-amz-algorithm": "AWS4-HMAC-SHA256",
        "x-amz-credential": "WWWWWWWW/20200318/us-east-1/s3/aws4_request",
        "x-amz-date": "20200318T133309Z",
        "x-amz-security-token": "XXXXXXXX",
        "policy": "YYYYYYYY",
        "x-amz-signature": "ZZZZZZZZ"
    }
}
Run Code Online (Sandbox Code Playgroud)

在 Postman 中,创建一个 POST 请求,并使用“form-data”输入您返回的所有字段,其字段名称与您在上面显示的 signedURL 中返回的字段名称完全相同。但是,不要设置内容类型。然后再添加一个名为“file”的键:

在此处输入图片说明

在 word 文件的右侧,如果您单击下拉菜单,您可以浏览到您的文件并附加它:

在此处输入图片说明

如果有帮助,我正在使用用 python 编写的 lambda 生成预签名 URL,以便用户可以上传附件。代码如下所示:

signedURL = self.s3.generate_presigned_post(
    Bucket= "my-s3-bucket",
    Key=putkey,
    Fields = {"acl": "public-read", "Content-Type": "multipart/form-data"},
    ExpiresIn = 15,
    Conditions = [
        {"acl": "public-read"},
        ["content-length-range", 1, 5120000]
        ]
    )
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。