当前位置: 首页 > 知识库问答 >
问题:

Angular/AWS S3-使用预签名url将文件上载到AWS S3

龚宏壮
2023-03-14

我正在开发一个特性,使用Angular/预签名url和API Gateway/lambda生成预签名url将文件上传到S3。

我的工作流描述如下:

  1. 从模板中获取选定文件
  2. 请求我的api(网关/lambda)使用文件名生成预签名的URL。

const body={filename:this.selectedfile.name}const preSignedUrl=await this.http.post('https://xxxxx.execute-api.eu-west-1.amazonaws.com/dev/v1/profile/avatar',body).ToPromise();

后端

我正在使用无服务器(lambda/API网关)来计算presignedurl。

兰姆达

const AWS = require('aws-sdk')
 
 
module.exports.uploadLargeFile = async (event) => {  
 
  console.log('1. Event: ', event.body);
  const reqBodyAsString = event.body || '{}';
  const fileName = JSON.parse(reqBodyAsString).fileName;
 
  return getUploadURL(fileName);
}
 
const getUploadURL = async (fileName) => {
  const s3Params = {
      Bucket: process.env.AVATAR_BUCKET,
      Expires: 60 * 60,
      ACL: 'public-read',
      Key: fileName 
  };
 
  const s3 = new AWS.S3();    
  try {
      const presinedUrl =  await s3.getSignedUrl('putObject', s3Params);
      return utiles.buildResponse(200, {presinedUrl })
  } catch (error) {
      return utiles.buildResponse(500, {error: 'facing some errors' })
 
  }
};

S3 CORS配置

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

前端

模板

 <input  type="file" (change)="onFileSelected($event)"/>
 <button (click)="onUpload()" > Upload to S3 </button>  

组件

selectedFile: File = null;  
  constructor(private http: HttpClient ) {}
 
  onFileSelected(event:any){
    this.selectedFile = <File> event.target.files[0]; 
  }
 
  async onUpload() {   
    console.log('1. SelectedFile: ', this.selectedFile); 
    const body = { fileName: this.selectedFile.name }
    const preSignedUrl = await this.http.post('https://xxxxx.execute-api.eu-west-1.amazonaws.com/dev/v1/profile/avatar', body).toPromise();  
    console.log('2. PreSignedURL: ', preSignedUrl)
    console.log('3. Upoloading File (binary) to S3')
 
    const upload = this.http.put(preSignedUrl.presinedUrl, this.selectedFile).toPromise();    
    upload.then(data => {
      console.log('=> ', data )
    }).catch(err => console.log('error: ', err))
  }

问题

当我使用postman(投递二进制文件)时,这段代码工作得很好。

但当我使用Angular时,我得到了这个错误:

HttpErrorResponse {headers: HttpHeaders, status: 403, statusText: "Forbidden", url: "https://bucket-photos-10042018-bucket.s3.eu-west-1.ama…Dlt4WBiu0uLfK8b0%2FWmT9xcKz6jOa0KpQxnWMqm4A%3D%3D", ok: false, …}error: "<?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>ASIA5PS6D3MHY4DGELXH</AWSAccessKeyId><StringToSign>PUT↵↵image/png↵1593696048↵x-amz-acl:public-read↵x-amz-security-token:IQoJb3JpZ2luX2VjEMX//////////wEaCWV1LXdlc3QtMSJHMEUCIARoXCbv7BKP9dVn5vhETAol3/qS0737isaWI25J1Uq+AiEAyzIe32BN9KfxcJhg1V5tZnxy6OatGUcOP7zXB0b2Wa8q6gEIXRABGgw5MjY4MzY1NzkwODciDGqkpU2I2+WNMsxTNCrHATPQ4MNNbrijo7GDZ/2zeUYgvBHshXkQQvcNVTBgD0PhKoSJ7VZsCa48J0aYAFXrpsGLrqZeXZkZjAhMxnXUGTFH3ymC2ZFgsHE1V8OOdhbbOSbBeKU7w92WDMNuF8SadrGT/Xl3uHUw/UPVzit5StD15T5sAjTbW4m7SYxRoEFXGq43IN62GOKQDgsaM2MMjSzzEEzY2agcKL8rNlySfWubZuqAKHfplGxz7yRH1uDshSV0uAzwLKdUDi0E1JjwkoyDDOs7mfAwn6L39wU64AGPsqOCEweNrGk1nscphBKiWKYFaht4RQM9Gqt236NXkHQBedxD7Xd3ZJlzpm/dCTyxN75DVLidggrYSTmc8GU4Nl6Rfe3UQ8L4aABSOPgGu5GlA61gelwmPstdTBPgYtzjpoM1ZlNi7MWImslkkpgLqFl1Ls1OtK1alcLF5bghXj6aIEweS6MYVGQiayaCO/0lYh1x7Vyz4A9qiSd5zWO5cwS2jz714p2JljabubYBuWfXhBDpwPYkCA6KXpzvfP3qfDlt4WBiu0uLfK8b0/WmT9xcKz6jOa0KpQxnWMqm4A==↵/dev-inmates-photos-bucket/aws-logo.png</StringToSign><SignatureProvided>JFfuW+hlCyKjZ1vOt3YsxqktikY=</SignatureProvided><StringToSignBytes>50 55 54 0a 0a 69 6d 61 67 65 2f 70 6e 67 0a 31 35 39 33 36 39 36 30 34 38 0a 78 2d 61 6d 7a 2d 61 63 6c 3a 70 75 62 6c 69 63 2d 72 65 61 64 0a 78 2d 61 6d 7a 2d 73 65 63 75 72 69 74 79 2d 74 6f 6b 65 6e 3a 49 51 6f 4a 62 33 4a 70 5a 32 6c 75 58 32 56 6a 45 4d 58 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 77 45 61 43 57 56 31 4c 58 64 6c 63 33 51 74 4d 53 4a 48 4d 45 55 43 49 41 52 6f 58 43 62 76 37 42 4b 50 39 64 56 6e 35 76 68 45 54 41 6f 6c 33 2f 71 53 30 37 33 37 69 73 61 57 49 32 35 4a 31 55 71 2b 41 69 45 41 79 7a 49 65 33 32 42 4e 39 4b 66 78 63 4a 68 67 31 56 35 74 5a 6e 78 79 36 4f 61 74 47 55 63 4f 50 37 7a 58 42 30 62 32 57 61 38 71 36 67 45 49 58 52 41 42 47 67 77 35 4d 6a 59 34 4d 7a 59 31 4e 7a 6b 77 4f 44 63 69 44 47 71 6b 70 55 32 49 32 2b 57 4e 4d 73 78 54 4e 43 72 48 41 54 50 51 34 4d 4e 4e 62 72 69 6a 6f 37 47 44 5a 2f 32 7a 65 55 59 67 76 42 48 73 68 58 6b 51 51 76 63 4e 56 54 42 67 44 30 50 68 4b 6f 53 4a 37 56 5a 73 43 61 34 38 4a 30 61 59 41 46 58 72 70 73 47 4c 72 71 5a 65 58 5a 6b 5a 6a 41 68 4d 78 6e 58 55 47 54 46 48 33 79 6d 43 32 5a 46 67 73 48 45 31 56 38 4f 4f 64 68 62 62 4f 53 62 42 65 4b 55 37 77 39 32 57 44 4d 4e 75 46 38 53 61 64 72 47 54 2f 58 6c 33 75 48 55 77 2f 55 50 56 7a 69 74 35 53 74 44 31 35 54 35 73 41 6a 54 62 57 34 6d 37 53 59 78 52 6f 45 46 58 47 71 34 33 49 4e 36 32 47 4f 4b 51 44 67 73 61 4d 32 4d 4d 6a 53 7a 7a 45 45 7a 59 32 61 67 63 4b 4c 38 72 4e 6c 79 53 66 57 75 62 5a 75 71 41 4b 48 66 70 6c 47 78 7a 37 79 52 48 31 75 44 73 68 53 56 30 75 41 7a 77 4c 4b 64 55 44 69 30 45 31 4a 6a 77 6b 6f 79 44 44 4f 73 37 6d 66 41 77 6e 36 4c 33 39 77 55 36 34 41 47 50 73 71 4f 43 45 77 65 4e 72 47 6b 31 6e 73 63 70 68 42 4b 69 57 4b 59 46 61 68 74 34 52 51 4d 39 47 71 74 32 33 36 4e 58 6b 48 51 42 65 64 78 44 37 58 64 33 5a 4a 6c 7a 70 6d 2f 64 43 54 79 78 4e 37 35 44 56 4c 69 64 67 67 72 59 53 54 6d 63 38 47 55 34 4e 6c 36 52 66 65 33 55 51 38 4c 34 61 41 42 53 4f 50 67 47 75 35 47 6c 41 36 31 67 65 6c 77 6d 50 73 74 64 54 42 50 67 59 74 7a 6a 70 6f 4d 31 5a 6c 4e 69 37 4d 57 49 6d 73 6c 6b 6b 70 67 4c 71 46 6c 31 4c 73 31 4f 74 4b 31 61 6c 63 4c 46 35 62 67 68 58 6a 36 61 49 45 77 65 53 36 4d 59 56 47 51 69 61 79 61 43 4f 2f 30 6c 59 68 31 78 37 56 79 7a 34 41 39 71 69 53 64 35 7a 57 4f 35 63 77 53 32 6a 7a 37 31 34 70 32 4a 6c 6a 61 62 75 62 59 42 75 57 66 58 68 42 44 70 77 50 59 6b 43 41 36 4b 58 70 7a 76 66 50 33 71 66 44 6c 74 34 57 42 69 75 30 75 4c 66 4b 38 62 30 2f 57 6d 54 39 78 63 4b 7a 36 6a 4f 61 30 4b 70 51 78 6e 57 4d 71 6d 34 41 3d 3d 0a 2f 64 65 76 2d 69 6e 6d 61 74 65 73 2d 70 68 6f 74 6f 73 2d 62 75 63 6b 65 74 2f 61 77 73 2d 6c 6f 67 6f 2e 70 6e 67</StringToSignBytes><RequestId>DD6A5C2957A647FF</RequestId><HostId>pXY2D5gEXY9+G81Tq/VwTEdMk3zTq4fCAsRmAjhneCgpt2buFQwxGScbjASC4vHfDSH/eK8mlGg=</HostId></Error>"headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}message: "Http failure response for https://bucket-photos-10042018-bucket.s3.eu-west-1.amazonaws.com/aws-logo.png?AWSAccessKeyId=ASIA5PS6D3MHY4DGELXH&Expires=1593696048&Signature=JFfuW%2BhlCyKjZ1vOt3YsxqktikY%3D&x-amz-acl=public-read&x-amz-security-token=IQoJb3JpZ2luX2VjEMX%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCWV1LXdlc3QtMSJHMEUCIARoXCbv7BKP9dVn5vhETAol3%2FqS0737isaWI25J1Uq%2BAiEAyzIe32BN9KfxcJhg1V5tZnxy6OatGUcOP7zXB0b2Wa8q6gEIXRABGgw5MjY4MzY1NzkwODciDGqkpU2I2%2BWNMsxTNCrHATPQ4MNNbrijo7GDZ%2F2zeUYgvBHshXkQQvcNVTBgD0PhKoSJ7VZsCa48J0aYAFXrpsGLrqZeXZkZjAhMxnXUGTFH3ymC2ZFgsHE1V8OOdhbbOSbBeKU7w92WDMNuF8SadrGT%2FXl3uHUw%2FUPVzit5StD15T5sAjTbW4m7SYxRoEFXGq43IN62GOKQDgsaM2MMjSzzEEzY2agcKL8rNlySfWubZuqAKHfplGxz7yRH1uDshSV0uAzwLKdUDi0E1JjwkoyDDOs7mfAwn6L39wU64AGPsqOCEweNrGk1nscphBKiWKYFaht4RQM9Gqt236NXkHQBedxD7Xd3ZJlzpm%2FdCTyxN75DVLidggrYSTmc8GU4Nl6Rfe3UQ8L4aABSOPgGu5GlA61gelwmPstdTBPgYtzjpoM1ZlNi7MWImslkkpgLqFl1Ls1OtK1alcLF5bghXj6aIEweS6MYVGQiayaCO%2F0lYh1x7Vyz4A9qiSd5zWO5cwS2jz714p2JljabubYBuWfXhBDpwPYkCA6KXpzvfP3qfDlt4WBiu0uLfK8b0%2FWmT9xcKz6jOa0KpQxnWMqm4A%3D%3D: 403 Forbidden"name: "HttpErrorResponse"ok: falsestatus: 403statusText: "Forbidden"url: "https://bucket-photos-10042018-bucket.s3.eu-west-1.amazonaws.com/aws-logo.png?AWSAccessKeyId=ASIA5PS6D3MHY4DGELXH&Expires=1593696048&Signature=JFfuW%2BhlCyKjZ1vOt3YsxqktikY%3D&x-amz-acl=public-read&x-amz-security-token=IQoJb3JpZ2luX2VjEMX%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCWV1LXdlc3QtMSJHMEUCIARoXCbv7BKP9dVn5vhETAol3%2FqS0737isaWI25J1Uq%2BAiEAyzIe32BN9KfxcJhg1V5tZnxy6OatGUcOP7zXB0b2Wa8q6gEIXRABGgw5MjY4MzY1NzkwODciDGqkpU2I2%2BWNMsxTNCrHATPQ4MNNbrijo7GDZ%2F2zeUYgvBHshXkQQvcNVTBgD0PhKoSJ7VZsCa48J0aYAFXrpsGLrqZeXZkZjAhMxnXUGTFH3ymC2ZFgsHE1V8OOdhbbOSbBeKU7w92WDMNuF8SadrGT%2FXl3uHUw%2FUPVzit5StD15T5sAjTbW4m7SYxRoEFXGq43IN62GOKQDgsaM2MMjSzzEEzY2agcKL8rNlySfWubZuqAKHfplGxz7yRH1uDshSV0uAzwLKdUDi0E1JjwkoyDDOs7mfAwn6L39wU64AGPsqOCEweNrGk1nscphBKiWKYFaht4RQM9Gqt236NXkHQBedxD7Xd3ZJlzpm%2FdCTyxN75DVLidggrYSTmc8GU4Nl6Rfe3UQ8L4aABSOPgGu5GlA61gelwmPstdTBPgYtzjpoM1ZlNi7MWImslkkpgLqFl1Ls1OtK1alcLF5bghXj6aIEweS6MYVGQiayaCO%2F0lYh1x7Vyz4A9qiSd5zWO5cwS2jz714p2JljabubYBuWfXhBDpwPYkCA6KXpzvfP3qfDlt4WBiu0uLfK8b0%2FWmT9xcKz6jOa0KpQxnWMqm4A%3D%3D"__proto__: HttpResponseBase

你能帮我弄清楚这个错误是从哪里开始的吗?

看起来请求中缺少了与签名匹配的东西?

事先谢谢你的帮助。

共有1个答案

司寇嘉茂
2023-03-14

最后,我找到了它不起作用的原因:)在生成PreSignedUrl时缺少contentType;

const s3Params = {
    Bucket: process.env.AVATAR_BUCKET,
    Expires: 60 * 60,
    ACL: 'public-read',
    Key: fileName,
    ContentType: 'image/jpeg' // need to be done dynamically
};
 类似资料:
  • 我正在尝试使用预先签名的URL将文件上传到Amazon的S3。我从生成URL的服务器获取URL https://com-example-mysite.s3-us-east-1.amazonaws.com/userFolder/ImageName?X-Amz安全令牌=xxfoox///xxbarxx= 不幸的是,当我将其传递给Refught2时,它会修改试图将其转换为URL的字符串。我设置了,它解决

  • 这里是我的node.js预签名URL的生成 那么我在URL生成或卷曲方面的问题在哪里呢?谢谢

  • 我正在尝试使用邮差上传一个文件。我已经通过点击“body”(在postman中)->二进制->选择文件附加了文件。我使用S3上载预签名的URL。在url中,文件的名称与我在Postman中选择的文件的名称完全相同。运行请求时,我得到一个错误: 但是,通过导出postman请求(通过单击“Code”)来获得curl命令,我得到了: 并添加一个用于上载文件的附加选项:

  • 问题内容: 我正在尝试使用预签名的URL将文件上传到Amazon的S3。我从生成URL的服务器获取URL,并将其作为JSON对象的一部分发送给我。我将URL作为字符串获取,如下所示: https://com-example-mysite.s3-us- east-1.amazonaws.com/userFolder/ImageName?X-Amz-Security- Token=xxfooxx%2F

  • 我正试图上传一个媒体文件(图片,任何扩展名jpg/png/jpeg或视频)到aws s3桶,从邮递员我创建了我的预签名url在我的后端如下 这成功地生成了一个url,但我似乎无法使用postman来测试它,这是我如何在postman中调整请求的截图 我所尝试的: 在上面的代码中,我尝试将签名版本v4添加到params中,但它给了我一个错误,说出了意外的关键字。我甚至尝试将其添加到aws配置和s3中

  • 但是,没有关于如何完成这一点的例子。此外,如果没有设置凭据,即使在向S3请求上载之前,SDK也会出错 JS SDK文档中提到了这一点,因此似乎有可能: