繁体   English   中英

Django AWS S3 - 400“错误请求”- 无法访问存储桶中的图像

[英]Django AWS S3 - 400 "Bad Request" - Can't access image from bucket

我最近决定将我的应用程序中使用的图像从根目录中的 static 文件夹合并到 AWS S3 存储桶中。

不幸的是,当我在浏览器中打开我的应用程序时出现此错误: localhost/:65 GET https://django-plantin-bugtracker-files.s3.amazonaws.com/profile_pics/aragorn_SztKYs6.jpg?AWSAccessKeyId=AKIA3KFS7YZNOMSRYG3O&Signature=fYWSQFdzTvtOF9OXAfw9yqfGyQc%3D&E

这很奇怪,因为我可以直接访问图像 URL(例如https://django-plantin-bugtracker-files.s3.us-east-2.amazonaws.com/default.jpg ),这让我相信我的应用程序只是没有正确访问它。

我取消阻止我的 S3 存储桶上的所有公共访问并将这些代码行添加到以下文件中:

在我的应用程序的settings.py ,我添加了:

AWS_STORAGE_BUCKET_NAME=config('AWS_S3_BUCKET_NAME')
AWS_ACCESS_KEY_ID = config('AWS_S3_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = config('AWS_S3_SECRET_ACCESS_KEY')

AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

在我的 S3 存储桶的Bucket Policy中:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::django-plantin-bugtracker-files/*"
        }
    ]
}

在我的 S3 存储桶的CORS

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

有谁知道为什么我的图片不会出现? 网页加载正常,Django 没有错误。

图像如下所示:

图片未加载示例

我发现出了什么问题。 我在我的应用程序文件夹的settings.py文件中缺少这行代码。 添加它解决了问题,图像现在出现了。

AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME

我检查了,您的文件已按预期公开

curl https://django-plantin-bugtracker-files.s3.amazonaws.com/profile_pics/aragorn_SztKYs6.jpg
Accept-Ranges: bytes
Content-Type: image/jpeg
Content-Length: 17532

所以这不是存储桶策略或 S3 的问题。 它必须是特定于您的应用程序的东西。

你可以尝试什么..

1. 确保您拥有正确的 S3 权限和策略。 通过 AWS S3 控制台中的权限选项卡访问特定存储桶的“策略”。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<your_bucket_name>/*"
        },
        {
            "Sid": "Statement2",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<your_bucket_name>/images/"
        }
    ]
}

2. 在你的项目环境中安装 WhiteNoiseMiddleware & django-storages。

pip install whitenoise
pip install django-storages

3. 在settings.py中将以下内容添加到MIDDLEWARE=

'whitenoise.middleware.WhiteNoiseMiddleware',

4. 需要在settings.py中添加以下内容才能正确处理来自 S3 的 URL。 处理由 django 中间件和 django-storages 自动完成

STATICFILES_LOCATION = 'static'
MEDIAFILES_LOCATION = 'media'

AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % os.environ['BUCKET_NAME']
AWS_ACCESS_KEY_ID = os.environ['AWS_KEY']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_ACC_KEY']
AWS_STORAGE_BUCKET_NAME = os.environ['BUCKET_NAME']
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'

MEDIA_ROOT = os.path.join (BASE_DIR, 'static/images/')
STATIC_ROOT = os.path.join (BASE_DIR, 'static')

STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)

5. 用于瞄准上传到精确的 S3 Bucket 文件夹。 (额外的)

在 setting.py 中设置媒体根目录:

MEDIA_ROOT = os.path.join (BASE_DIR, 'static/images/')

在 models.py 中使用ImageFiled并添加upload_to=获取文件夹名称并在第一次上传时创建它:

image_variable = models.ImageField(null=True, default="{default_filename)", upload_to='uploads/') 

参考: django- storages , whiteNoiseMiddelware , S3 Access Troubleshooting

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM