我正在按照本教程将简单的照片上传服务部署到 S3 存储桶。
我使用以下策略创建了一个新角色
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
]
}
]
}
授予存储桶中的所有授权 AWS 用户列表和读/写访问权限,设置以下 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>
生成了新的 Cognito 身份池并运行上述链接中的脚本。它运行成功,打开一个新相册,我可以在 S3 控制台中看到它,但是当我尝试将照片上传到相册时,出现错误:
BUCKET_NAME.amazonaws.com/ALBUM_NAME//PHOTO_NAME.jpeg?uploads:1 POST https://BUCKET_NAME.amazonaws.com/ALBUM_NAME//PHOTO_NAME.jpeg?uploads 403 (Forbidden)
当我尝试访问脚本生成的链接时,我得到以下 XML:
<Error>
<Code>InvalidRequest</Code>
<Message>
Key is not expected for the GET method ?uploads subresource
</Message>
<RequestId>******</RequestId>
<HostId>
******
</HostId>
</Error>
知道为什么会出现这个问题吗?
您正在执行 HTTP POST,而不是 HTTP PUT。 如果要传递密钥,则应使用 PUT。 如果要执行 POST,则需要按照本页所述在正文中传递密钥。
您缺少 s3 存储桶的部分权限。
在此示例中,您希望向 AWS 账户中的 IAM 用户授予对您的某个存储桶(示例存储桶(的访问权限,并允许用户添加、更新和删除对象。
除了向用户授予 s3:PutObject、s3:GetObject 和 s3:DeleteObject 权限外,该策略还授予 s3:ListAllMyBuckets、s3:GetBucketLocation 和 s3:ListBucket 权限。这些是控制台所需的其他权限。有关向用户授予权限并使用控制台对其进行测试的示例演练,请参阅示例演练:使用用户策略控制对存储桶的访问。
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":[
"s3:ListAllMyBuckets"
],
"Resource":"arn:aws:s3:::*"
},
{
"Effect":"Allow",
"Action":[
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource":"arn:aws:s3:::examplebucket"
},
{
"Effect":"Allow",
"Action":[
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource":"arn:aws:s3:::examplebucket/*"
}
]
}
http://docs.aws.amazon.com/AmazonS3/latest/dev/example-policies-s3.html
我也有同样的问题。我没有删除ACL:'public-read',而是将其更改为"public-read-write"并且它起作用了。我只能假设由于存储桶策略是读写的,因此尝试将其设置为只读只会导致冲突......但只是猜测。
这很旧,但以防万一有人在使用 Cognito 上传时偶然发现它。
就我而言,问题是我的 S3 (us-east-1)
的区域与 Cognito 服务器区域(eu-west-1)
不同。大多数在线示例仅设置一个区域,默认情况下上传使用相同的区域。
所以在Javascript中,要进行身份验证,你需要设置Cognito区域:
AWS.config.region = 'eu-west-1'; // Cognito Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'eu-west-1:51a4f410-7694-4222-89b5-...',
});
然后,在上传之前,请设置 S3 存储桶区域:
var s3 = new AWS.S3({
region: 'us-east-1', //Bucket region
apiVersion: '2006-03-01',
params: {Bucket: [BUCKET-NAME]}
});