I'm working on a Django(3) project which is deployed at Heroku. I'm trying to connect AWS S3 using Django Storages to upload Static and Media files to S3 Bucket.
Note: I have googled a lot and tried every solution I found, but nothing solved my issue, so don't mark this as duplicate, please!
I have created an S3 bucket with the Public access enabled and added the following CORS configuration:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"PUT",
"POST"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
Also, created an IAM user with programmatic access and gives the permission as S3FullAccess
And here's what I have in **settings.py**
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_QUERYSTRING_AUTH = False
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
AWS_S3_REGION_NAME = 'us-east-1'
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'
If I open files from the bucket directly I can see the file in the browser, but when I load my site (pythonist.org) these files return with 403 forbidden
Here's the response from browser's Network tab for a file:
Summary
URL: https://s3.amazonaws.com/pythonist.org/css/normalize.css
Status: 403 Forbidden
Source: Network
Initiator:
pythonist.org:18
Don't know what's wrong here, Thanks in advance!
It seems your bucket is not publicly accessible. Your public bucket should have a bucket policy like this one (example with some deleted attributes):
{
"Id": "Policy1640778083903",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1640778050694",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::pythonist.org",
"arn:aws:s3:::pythonist.org/*"
],
"Principal": {
"AWS": [
"YOUR_IAM_USER"
]
}
},
{
"Sid": "Stmt1640778082281",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::pythonist.org/*",
"Principal": "*"
}
]
}
Your IAM user has any permission while the public can only get the objects (not from the root directory here, change to your needs). Create your policy with AWS Policy Generator