【发布时间】:2018-02-10 01:49:27
【问题描述】:
我是 Amazon AWS 的新手,我正在尝试设置一个系统来为用户上传图像。设置完所有内容后,我无法验证令牌。下面,我将解释我所做的所有配置。
我创建了一个 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
【问题讨论】:
-
endpoint: cloudFrontUrl无效,在这里...您混合了两个不同的概念。要授权通过 CloudFront 发送的请求,您需要使用不同算法的 CloudFront 签名 URL。这反过来又是有问题的,因为根据存储桶策略,CloudFront URL 对于源访问身份可以执行的任何方法都是有效的。 -
感谢您的信息。建议的方法是什么?我真的不需要保护获取操作,但是对于添加和删除,我想保护这一点,我想通过 CloudFront 进行所有操作。我想我可以直接在 S3 上进行添加和删除,然后在 CloudFront 上并接受用户可以通过 S3 和 CloudFront URL 访问对象的事实,除非有办法实现我想要的做什么?
-
我正在对一些可用选项进行完整的解释。您能否阐明为什么要通过 CloudFront 进行所有操作?这种方法没有任何问题,并且有一些优势,但有些人认为通过 CloudFront 上传会与缓存交互,但事实并非如此。此外,您的价格等级选择以及存储桶和用户的位置可能会使 S3 Transfer Acceleration 成为上传的更好选择。它与通过 CloudFront 上传的技术完全相同(它使用 CloudFront 网络),但可能是一种更有利的定价模型。你的想法?
-
看起来我完全掩盖了关于传输加速的那篇文章。谢谢你的信息。这是否意味着我可以像直接上传到 S3 一样使用 JavaScript sdk 启用传输加速的临时凭证?我假设我不必面对与 CloudFront 相同的困境,但只是想确认一下。我还假设我可以将 CloudFront 用于获取请求,并为放置和删除请求启用传输加速?
-
正确。传输加速有一个“陷阱”——不要在存储桶名称中使用任何点。 Transfer Acceleration 启用了两个新端点,
example-bucket.s3-accelerate.amazonaws.com和example-bucker.s3-accelerate.dualstack.amazonaws.com。签名 URL 使用与标准 S3 签名 URL 相同的算法。
标签: amazon-web-services amazon-s3 aws-sdk amazon-cloudfront