Я использую boto3 и django-storages в своем приложении Django для обслуживания файлов из AWS S3. Я бы хотел, чтобы мои статические файлы были общедоступными, а другие файлы — частными. У меня вроде работает, но не совсем. Мои статические файлы обслуживаются так, как если бы они были частными, с предварительно подписанным ключом. В моем файле шаблона, когда я использую:
<img src="{% static 'images/3d-house-nav-gray.png' %}">
вместо того, что я хочу
<img src="https://mybucket.s3.amazonaws.com/static/images/3d-house-nav-gray.png">
я собираюсь
<img id="home-img" src="https://mybucket.s3.amazonaws.com/static/images/3d-house-nav-gray.png?AWSAccessKeyId=AKIA1234564LQ7X4EGHK&Signature=123456gIBTFlTQKCexLo3UJmoPs%3D&Expires=1621693552">
На самом деле это работает, когда шаблоны рендерятся с сервера как часть HTTPResponse, но не когда подобное изображение просто включается как часть, скажем, файла .css. В таком случае я получу:
Failed to load resource: the server responded with a status of 403 (Forbidden)
(Я обнаружил, что если я скопирую и вставлю проблемную ссылку на изображение и заменю &
на &
, тогда у меня будет доступ, еще одна загадка.)
Вот как я настроил AWS:
AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
AWS_STORAGE_BUCKET_NAME = 'mybucket'
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
AWS_DEFAULT_ACL = None
AWS_LOCATION = 'static'
STATICFILES_STORAGE = 'myapp.storage_backends.StaticStorage'
DEFAULT_FILE_STORAGE = 'myapp.storage_backends.MediaStorage'
AWS_S3_URL = 'https://%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
STATIC_DIRECTORY = '/static/'
MEDIA_DIRECTORY = '/media/'
STATIC_URL = AWS_S3_URL + STATIC_DIRECTORY
MEDIA_URL = AWS_S3_URL + MEDIA_DIRECTORY
Где myapp.storage_backends.py
содержит:
from storages.backends.s3boto3 import S3Boto3Storage
class MediaStorage(S3Boto3Storage):
location = 'media'
file_overwrite = False
class StaticStorage(S3Boto3Storage):
location = 'static'
file_overwrite = True
А на AWS S3 моя политика ведра настроена так:
{
"Version": "2012-10-17",
"Id": "Policy1621539673651",
"Statement": [
{
"Sid": "Stmt1621539665305",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::063896663644:user/mylogin"
},
"Action": [
"s3:GetObject",
"s3:GetObjectAcl",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::mybucket/*"
},
{
"Sid": "Stmt1621539600741",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/static/*"
}
]
}
Как я могу исправить это, чтобы сделать некоторые файлы (например, все в static/) неподписанными и общедоступными, а другие файлы подписанными и закрытыми?