通过django s3中间件保存文件时获取Http403(但可以在shell中使用boto进行保存) [英] Getting Http403 when saving files through django s3 middleware (but can save using boto in shell)
问题描述
我一直试图通过django应用程序将用户上传的文件保存到s3存储桶中.我正在使用 django-s3-storage
中间件,但是我一直在获取:
I have been trying to save user uploaded files to my s3 bucket via my django application. I'm using the django-s3-storage
middleware, but I keep getting:
S3ResponseError:禁止403(访问被拒绝)
S3ResponseError: 403 Forbidden (Access Denied)
我正在使用以下设置:
MEDIAFILES_LOCATION = 'media'
AWS_S3_CUSTOM_DOMAIN = 'my-bucket.s3-website-eu-west-1.amazonaws.com'
AWS_S3_HOST = 's3-website-eu-west-1.amazonaws.com'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'django_s3_storage.storage.StaticS3Storage'
#S3 settings from https://github.com/etianen/django-s3-storage
AWS_ACCESS_KEY_ID = "xxx"
AWS_SECRET_ACCESS_KEY = "yyy"
AWS_S3_BUCKET_NAME = "my-bucket"
AWS_S3_CALLING_FORMAT = "boto.s3.connection.OrdinaryCallingFormat"
# Make user uploaded files public
AWS_S3_BUCKET_AUTH = False
AWS_S3_MAX_AGE_SECONDS = 60*60*24*365 # 1 year
AWS_S3_GZIP = True
我知道凭据是有效的:
from boto.s3.connection import S3Connection
from django.conf import settings
conn = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
b = conn.get_bucket('my-bucket')
key = b.get_key('test.txt')
print(key.get_contents_as_string())
>>>this is a test
from boto.s3.key import Key
k = Key(b)
k.key = 'test2.txt'
k.set_contents_from_string('another test')
>>>12
我也设置了一个完全开放的CORS策略(同时试图从我的开发机上使之工作):
I've set a completely open CORS policy too (while trying to get this working from my dev machine):
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
那是什么阻止我通过中间件进行身份验证? (或者是什么原因导致了403?)
So what's stopping me authenticating via the middleware? (Or what else could be causing the 403?)
存储桶策略,允许访问存储桶my-bucket
的IAM用户production
.我删除了用户ARN数字,并替换为x
.
bucket policy allowing access to IAM user production
for bucket my-bucket
. I've removed the user ARN digits and replaced with x
.
{
"Version": "2016-12-30",
"Statement": [
{
"Sid": "PublicReadForGetBucketObjects",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxxx:user/production"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
根据此错误,该错误不是签名错误.我使用的是Django 1.10,Boto 2.45,django-s3-storage 0.9.11.
The error is not a signature error as per this bug. I'm on django 1.10, boto 2.45, django-s3-storage 0.9.11.
S3ResponseError at /the-url/
S3ResponseError: 403 Forbidden
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message>
好,发生了一件奇怪的事情(我不记得在设置中进行了任何更改以导致此问题):我上传了一个文件,没有错误返回.该文件按照模型定义image0 = models.ImageField(upload_to="product_images")
保存.然后可以在https://s3.amazonaws.com:443/productimages/myimage.jpg
上找到该文件(嗯?为什么?).在http://my-bucket.s3-website-eu-west-1.amazonaws.com/media/productimages/myimage.jpg
上 不 可用,在我的存储桶的media/productimages/myimage.jpg
中也不可见.
Edit 2:
OK, this weird thing happened (I don't recall having changed anything in the settings to cause this): I upload a file, and no error is returned. The file is saved as per the model definition image0 = models.ImageField(upload_to="product_images")
. The file is then available at https://s3.amazonaws.com:443/productimages/myimage.jpg
(huh? why?). It is not available at http://my-bucket.s3-website-eu-west-1.amazonaws.com/media/productimages/myimage.jpg
, nor is it visible in my bucket's media/productimages/myimage.jpg
.
所以看来s3或中间件正在发生一些有趣的事情.有什么想法吗?
So it seems that something funny is going on with either s3 or the middleware. Any ideas?
推荐答案
使用描述的存储桶此处.您的存储桶名称是否符合DNS?
Using bucket described here. There are two access methods - path, and virtual hosted. More on that here. Is your bucket name is DNS compliant?
这篇关于通过django s3中间件保存文件时获取Http403(但可以在shell中使用boto进行保存)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!