Why does S3 (using with boto and django-storages) give signed url even for public files?
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 2 Looping
--
Chapters
00:00 Why Does S3 (Using With Boto And Django-Storages) Give Signed Url Even For Public Files?
00:40 Accepted Answer Score 29
01:07 Answer 2 Score 5
01:17 Answer 3 Score 1
01:35 Answer 4 Score 2
02:29 Thank you
--
Full question
https://stackoverflow.com/questions/1677...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #django #amazons3 #boto #djangostorage
#avk47
ACCEPTED ANSWER
Score 29
AWS_QUERYSTRING_AUTH sets the default behavior, but you can override it when you create an instance of S3BotoStorage, by passing in an additional argument to the initializer:
S3BotoStorage(bucket="foo", querystring_auth=False)
So if you have one bucket private and another bucket public, you can set the querystring_auth argument appropriately and get your desired behavior.
ANSWER 2
Score 5
put this in your settings.py
AWS_QUERYSTRING_AUTH = False
ANSWER 3
Score 2
You can create separate storage types for separate folders, directories and manage the access permission there.
With Django - create a file you can call "storage_aws.py" and add the following:
from storages.backends.s3boto3 import S3Boto3Storage
class PublicMediaStorage(S3Boto3Storage):
    location = 'media/location2/public'
    default_acl = 'public-read'
    file_overwrite = False
    querystring_auth=False
class PrivateMediaStorage(S3Boto3Storage):
    location = 'media/location1/private'
    default_acl = 'private'
    file_overwrite = False
    custom_domain = False
    querystring_auth=True
use default_acl to define the access (public or private) use location to define location - (you can specify paths) like
location1 = 'media/location1/private'
location2 = 'media/location2/public'
*Note the querystring_auth=False or True
Then when you define your model, you can specify which location to use for which model
from django.db import models
from appname.storage_aws import PublicMediaStorage, PrivateMediaStorage
class Upload(models.Model):
    file = models.FileField(storage=PublicMediaStorage())
class UploadPrivate(models.Model):
    file = models.FileField(storage=PrivateMediaStorage())
The private files will have query string while the public ones will not, as defined in the "storage_aws.py' file
ANSWER 4
Score 1
Another way to get around this is to set AWS_S3_CUSTOM_DOMAIN in your settings. @see: https://github.com/jschneier/django-storages/blob/master/storages/backends/s3boto.py#L478
(tested with boto==2.38.0 and django-storages-redux==1.3)