Setting up media file access on AWS S3

五迷三道 提交于 2020-04-30 11:25:06

问题


Im using boto3 and django-storage libraries for apload media files of my django project.

storage_backends.py

 class PrivateMediaStorage(S3Boto3Storage):
    location = settings.AWS_STORAGE_LOCATION
    default_acl = 'private'
    file_overwrite = False
    custom_domain = False

class PublicStaticStorage(S3Boto3Storage):
    location = settings.AWS_PUBLIC_STATIC_LOCATION

settings.py

AWS_STORAGE_LOCATION = 'media/private'
AWS_LOCATION = 'static'
AWS_PUBLIC_STATIC_LOCATION = 'static/'
DEFAULT_FILE_STORAGE = 'path.to.PrivateMediaStorage'

models.py

class Documents(models.Model):
    """ uploaded documents"""

    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    upload = models.FileField(storage=PrivateMediaStorage())
    filename = models.CharField(_('documents name'), max_length=255, blank=True, null=True)
    datafile = models.FileField()
    created = models.DateTimeField(auto_now_add=True)
    type = models.ForeignKey(Doctype, on_delete=models.CASCADE, blank=True)

File loading works well. But there is a point I don't understand, and the link to the file looks wrong (it contains static instead of media). Looks like

https://myhost.s3.amazonaws.com/static/class-descriptions_1.csv

And else about access. Now that I click on the link to the file, I get a message

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>4B8296F8F77491F5</RequestId>
<HostId>
CG96q+LGWcvsIK2YkuaE2wExL8/YTqH1PmjOSFGAqcgaKaTYnOet1QoItGJhW1Oj
</HostId>
</Error>

This is normal for unregistered users, but how do I allow users registered in my Django project to see this file?


回答1:


You have to use pre-signed URLs to implement this functionality. All users can access S3 objects if the bucket is public. If you want to restrict access, then the bucket has to be private and you need to generate pre-signed URLs per user.

https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-presigned-urls.html




回答2:


To make the media urls come from a different place, you need to override DEFAULT_FILE_STORAGE settings:

DEFAULT_FILE_STORAGE = 'path.to.PrivateMediaStorage'

Secondly, if you haven't defined AWS_DEFAULT_ACL in settings, then the files will use ACL inherited from the bucket. Probably bucket has been created with ACL private. Thats why the files can't be accessed.

Finally, regarding the access error. If the ACL is private, then no one can access it apart from the owner. So you need to change the ACL of the directories. You can use s3tools for that. For example:

s3cmd setacl --recursive s3://<bucket-name> --acl-public

Also

This is normal for unregistered users, but how do I allow users registered in my Django project to see this file?

Thats not how ACL works. ACL access needs to be set from S3 bucket. So you can't forbid user from accessing the contents from bucket if ACL is set to public-read.

As per @vikyol's answer, there is a way to send pre-signed URLs to user.

For more information on Canned ACL, please check the documentation by amazon.



来源:https://stackoverflow.com/questions/57520553/setting-up-media-file-access-on-aws-s3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!