通过django s3中间件保存文件时获取Http403(但可以在shell中使用boto保存)

Esc*_*her 5 django amazon-s3 boto amazon-web-services

我一直试图通过我的django应用程序将用户上传的文件保存到我的s3存储桶中.我正在使用django-s3-storage中间件,但我一直在:

S3ResponseError:403禁止访问(拒绝访问)

我正在使用这些设置:

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
Run Code Online (Sandbox Code Playgroud)

我知道凭证是有效的:

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
Run Code Online (Sandbox Code Playgroud)

我也设置了一个完全开放的CORS策略(同时尝试从我的开发机器上运行):

<?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>
Run Code Online (Sandbox Code Playgroud)

那么是什么阻止我通过中间件进行身份验证?(或者还有什么可能导致403?)

编辑:

存储桶策略允许访问production存储桶的IAM用户my-bucket.我删除了用户ARN数字并替换为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/*"
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

该错误是不是一个签名错误按照这个bug.我在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>
Run Code Online (Sandbox Code Playgroud)

编辑2:

好的,这个奇怪的事情发生了(我不记得在设置中改变了什么导致这个):我上传了一个文件,并且没有返回任何错误.根据模型定义保存文件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.

因此,无论是s3还是中间件,似乎都会发生一些有趣的事情.有任何想法吗?