我是亚马逊AWS的新手,并且正在尝试设置系统为用户上传图像。完成所有设置后,我无法验证令牌。下面,我将解释我所做的所有配置。Amazon CloudFront和S3
我创建一个S3桶和我配置CORS该桶:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
接下来,我设置一个指向此S3桶一个CloudFront的分布。它被设置为允许所有HTTP方法(包括“PUT”)。还会创建原始访问身份,以便图像只能通过CloudFront url而不是S3查看。
然后我创建了一个IAM用户,并创建了一个政策时,该用户,这样我可以申请临时证书,当我需要通过CloudFront的上传图片:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1504225496000",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"*"
]
}
]
}
现在,我设置了权限仅供开发使用。最终我会添加更严格的权限。
一旦完成,然后我要求临时凭证从API就像这样:
var securityClient =
new AmazonSecurityTokenServiceClient(Variables.AWSUserWriteId, Variables.AWSUserWriteKey);
var request = new GetSessionTokenRequest
{
DurationSeconds = 900
};
var tempCredentials = await securityClient.GetSessionTokenAsync(request);
return new ApiResponse(Enums.ResponseStatus.Success, new JObject
{
{"id", tempCredentials.Credentials.AccessKeyId},
{"key", tempCredentials.Credentials.SecretAccessKey},
{"token", tempCredentials.Credentials.SessionToken}
}, null);
这是返回给浏览器客户端(注意,我能够顺利拿到三个值)。
使用这些值,我使用AWS-SDK调用上传过程:
let id = response.data.JsonData.id;
let key = response.data.JsonData.key;
let token = response.data.JsonData.token;
let s3 = new AWS.S3({
accessKeyId: id,
secretAccessKey: key,
sessionToken: token,
endpoint: cloudFrontUrl //https://d3goqf5vihdmh2.cloudfront.net
});
s3.upload({Body: file, Bucket: amazonS3BucketName, Key: file.name}, (err, data) => {
console.log(err);
console.log(data);
let hello = "hello";
}).on("httpUploadProgress", evt => {
console.log(evt);
});
但是,做这一切后,会返回一个错误:
"The provided token is malformed or otherwise invalid."
用户有充分的权限,并且据我所知,我应该正确设置所有内容,除非我错过了某些内容?在Google和文档搜索之后,我找不到任何解决方案,我完全陷在这里。
编辑:这里是实际出去的请求的更多信息。这些是请求头,通过谷歌浏览器开发工具提供:
:authority:d3goqf5vihdmh2.cloudfront.net
:method:PUT
:path:/**removingforprivacy**.development/**removingforprivacy**.png
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, br
accept-language:en-US,en;q=0.8
authorization:AWS4-HMAC-SHA256 Credential=**removingforprivacy**/20170901/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-
amz-security-token;x-amz-user-agent,
Signature=180d55d69eb0577b77d14b8938c675cbd8798924132c7367d02fbd59b5e8a3d3
content-length:33041
content-type:application/octet-stream
origin:http://localhost:3000
referer:http://localhost:3000/postnew
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
x-amz-content-sha256:UNSIGNED-PAYLOAD
x-amz-date:20170901T024531Z
x-amz-security-token:FQoDYXdzEMz//////////wEaDDJE64k3fztWLnZWJiKrAbIUNroRDzBfHcFJrPTUIgNSKFWdZDM4Nt0a7UCxwnWopLRDJAMiwt/gX1svqe5ZJsUL+yHTubJylLVvIIZdxsGGCeSZhmaquyd5jWsx9n+PeHB5MFbxkcDdRWhaQ8eXobABH0Q53xxH/zBXxIZTn/qEERgHPjfaPVLLmzQmbd6+toc/WQX5y3HZMvf7ZgTh3KdoHWDwJEmCeYx6NuyNpR9NIiubVvI/2gH8zijGk6PNBQ==
x-amz-user-agent:aws-sdk-js/2.107.0 callback
*'端点:cloudFrontUrl * *无效,这里...您正在混合两个不同的概念。要授权通过CloudFront发送的请求,您需要使用CloudFront签名的URL,该URL使用不同的算法。这反过来是有问题的,因为CloudFront URL对于每个存储桶策略的源访问标识可以执行的任何方法都是有效的。 –
感谢您的信息。建议的方式是什么?我并不需要确保获得操作,但是对于添加和删除操作,我想确保这一点,并且我希望通过CloudFront执行所有操作。我想我可以继续,直接在S3上进行添加和删除操作,然后在CloudFront上进行操作,并使用户可以通过S3和CloudFront URL访问对象,除非有办法实现我想要的功能做? – Stalfos
我正在对一些可用选项进行完整说明。您能否澄清为什么您想通过CloudFront执行所有操作?这种方法没有任何问题,并且它有一些优势,但有些人认为通过CloudFront进行的上传与缓存进行交互,但它们不会。此外,您的价格等级选择以及存储桶和用户的位置可能会使S3 Transfer Acceleration成为上传的更好选择。它与通过CloudFront(它使用CloudFront网络)上传的技术完全相同,但可能是更有利的定价模式。你的想法? –