INTRO
- I am following this guide as recommended, here is the guide's GitHub repo.
- I have created an AmazonS3FullAccess to it as well
- I am using the guide's 3rd example "Mixing public assets and private assets" with static, media public, media, private version.
- If the user log in (local development environment) he Upload Files from the website but he can NOT access them from the website only from the AWS S3 management website.
- Currently I am blocking all public access as it is in the guide (AWS S3 management panel settings)
- I have added these lines to my CORS configuration editor from this other guide
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
- Switched on a central EU server that is more local to me. NOT worked I got the same error.
storage_backends.py
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class StaticStorage(S3Boto3Storage):
location = settings.AWS_STATIC_LOCATION
class PublicMediaStorage(S3Boto3Storage):
location = settings.AWS_PUBLIC_MEDIA_LOCATION
file_overwrite = False
class PrivateMediaStorage(S3Boto3Storage):
location = settings.AWS_PRIVATE_MEDIA_LOCATION
default_acl = 'private'
file_overwrite = False
custom_domain = False
settings.py
AWS_ACCESS_KEY_ID = 'DSHUGASGHLASF678FSHAFH'
AWS_SECRET_ACCESS_KEY = 'uhsdgahsfgskajgjkafgjkdfjkgkjdfgfg'
AWS_STORAGE_BUCKET_NAME = 'MYSTORAGE289377923'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
AWS_STATIC_LOCATION = 'static'
STATICFILES_STORAGE = 'mysite.storage_backends.StaticStorage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, AWS_STATIC_LOCATION)
AWS_PUBLIC_MEDIA_LOCATION = 'media/public'
DEFAULT_FILE_STORAGE = 'mysite.storage_backends.PublicMediaStorage'
AWS_PRIVATE_MEDIA_LOCATION = 'media/private'
PRIVATE_FILE_STORAGE = 'mysite.storage_backends.PrivateMediaStorage'
AWS_S3_HOST = "s3.eu-central-1.amazonaws.com"
S3_USE_SIGV4 = True
AWS_S3_REGION_NAME = "eu-central-1"
models.py
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from mysite.storage_backends import PrivateMediaStorage
class Document(models.Model):
uploaded_at = models.DateTimeField(auto_now_add=True)
upload = models.FileField()
class PrivateDocument(models.Model):
uploaded_at = models.DateTimeField(auto_now_add=True)
upload = models.FileField(storage=PrivateMediaStorage())
user = models.ForeignKey(User, related_name='documents')
views.py
from django.contrib.auth.decorators import login_required
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from .models import Document, PrivateDocument
class DocumentCreateView(CreateView):
model = Document
fields = ['upload', ]
success_url = reverse_lazy('home')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
documents = Document.objects.all()
context['documents'] = documents
return context
@method_decorator(login_required, name='dispatch')
class PrivateDocumentCreateView(CreateView):
model = PrivateDocument
fields = ['upload', ]
success_url = reverse_lazy('profile')
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return super().form_valid(form)
ERROR
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>56fg67dfg56df7g67df</RequestId>
<HostId>
hsiugYIGYfhuieHF7weg68g678dsgds78g67dsg86sdg68ds7g68ds7yfsd8f8hd7
</HostId>
</Error>
Things That I have Tried So Far
- There was an in between period where it have created the AWS link and also added the file to a local "media" folder. But since I have deleted the"Media folder" and it only creates URL links, and actually uploads them to the S3 bucket
- I have found the same question on aws forum but it has not been answered
- Access rights https://stackoverflow.com/questions/21609842/django-aws-s3-bucket-authenticated-access-to-s3-bucket (I don't understand this answer https://stackoverflow.com/a/21614550/10270590 )
- "use AWS4-HMAC-SHA256"
- Specifying region of the S3 host to the correct usage https://github.com/aws/aws-sdk-js/issues/829
- site to look up your region - https://docs.aws.amazon.com/general/latest/gr/rande.html
- I have also received this as a recommendation "Most new regions only support
AWS4-HMAC-SHA256
- if your code doesn't support this authentication scheme and only created "v2 signatures" create your bucket in one of the old regions, e.g. in Europe it seems to be only Ireland - check it out here: https://docs.aws.amazon.com/general/latest/gr/signature-version-2.html" - I am in the European Union with my testing machine - and I set up a USA base S3 bucket - how can I configure the Django app OR the AWS S3 Bucket so it will allow it to be accessed from anywhere (it would be especially important that the app is deployed that from around the world people can access it). A guy from the same video's comment section commented the the following
Steve D Great video series, just to say I am using an S3 bucket in Europe and needed to add additional settings AWS_S3_HOST = "s3.eu-west-2.amazonaws.com" and AWS_S3_REGION_NAME="eu-west-2" to make it work
- This was the exact code I have added to the settings based on and in addition to the original Guide's code. When I switch images it works but when I leave profile settings and go back the image disappears and gives the original error):
AWS_S3_HOST = "s3.eu-central-1.amazonaws.com"
S3_USE_SIGV4 = True
AWS_S3_REGION_NAME = "eu-central-1"
Most new regions only support
AWS4-HMAC-SHA256
- if your code doesn't support this authentication scheme and only created "v2 signatures" create your bucket in one of the old regions, e.g. in Europe it seems to be only Ireland - check it out here: https://docs.aws.amazon.com/general/latest/gr/signature-version-2.htmlBTW Your S3 upload/download code should be using some standard AWS SDK - for Python it is boto3. These official SDKs support all the right authentication methods, new regions, etc. Don't roll out your own SDK.
Hope that helps :)