【发布时间】:2020-12-10 19:23:24
【问题描述】:
在我的 Angular 项目中,我使用从 aws lambda 函数生成的预签名 url 将 pdf 文档上传到 s3 存储桶。现在使用 POSTMAN 上传没有任何错误,但是在带有 http PUT 请求的 Angular 应用程序中会给出 403 Forbidden Error。
错误
"<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>There were headers present in the request which were not signed</Message><HeadersNotSigned>x-amz-security-token</HeadersNotSigned><RequestId>7A2E66135748DFF3</RequestId><HostId>BT9uCZUdjI1HqycVR2QdzjyzkhKXOrVEJE5xVToeVbQup=</HostId></Error>"
这是我的代码和设置:
Lambda 函数
async function getSignedUrlForResume(fileName){
const urlExpiryDuration = 5; //minutes
console.log("inside get signed Url");
const key = "Resume/"+fileName;
var response = "";
const s3Params ={
Bucket: process.env.S3_BUCKET_NAME,
Key: key,
Expires: urlExpiryDuration*60,
ACL: 'public-read',
ContentType: "application/pdf"
};
const s3 = new AWS.S3();
try {
const signedUrl = await s3.getSignedUrl('putObject', s3Params);
response = {signedUrl: signedUrl};
return response;
} catch (error) {
response = error;
return response;
}
}
Component.ts 文件:
async addResume(){
let signedUrl : string = null;
let fileName: string = this.candidateService.candidateRecords['records'][this.candidateService.indexOfCandidate]['candidate_id']
+"_"+
this.candidateService.candidateRecords['records'][this.candidateService.indexOfCandidate]['first_name']
+"_"+
this.candidateService.candidateRecords['records'][this.candidateService.indexOfCandidate]['last_name'];
console.log("File Name: " +fileName);
this.file = event[0];
await this.candidateService.getSignedUrl(fileName).then(
(response: []) => {
signedUrl = response['signedUrl'];
}
);
console.log(signedUrl);
console.log(this.file)
await this.candidateService.uploadResume(signedUrl, this.file).then
(data => {
console.log("Upload Response:" +data);
}).catch((err: Error) => {
console.log('Error: '+ err);
});
}
组件服务
getSignedUrl(fileName: string){
let queryParams = new HttpParams();
queryParams = queryParams.set('fileName', fileName).set('funcName', 'getSignedUrlForResume');
return this.http.get(AppConstants._API_END_URL, {params: queryParams})
.pipe(
retryAfterDelay(this.delayDuration),
catchError((errorResponse:Error) => {
return throwError(errorResponse.message);
}
)
).toPromise();
}
uploadResume(signedUrl: string, file: File){
// Delay not added for upload to s3. since no RDS is used
return this.http.put(signedUrl, file, {headers: {'Content-Type': file.type}}).toPromise();
}
}
HTML 部分:
<input hidden type="file" #fileInput (change)="uploadFile($event.target.files)"
accept="application/pdf">
【问题讨论】:
标签: angular amazon-web-services http amazon-s3 aws-lambda