微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何让 Django 在 AWS S3 上将一些文件设为公共文件和媒体文件私有没有 403 错误?

如何解决如何让 Django 在 AWS S3 上将一些文件设为公共文件和媒体文件私有没有 403 错误?

我在我的 Django 应用程序中使用 boto3django-storages 来提供来自 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&amp;Signature=123456gIBTFlTQKCexLo3UJmoPs%3D&amp;Expires=1621693552">

当模板作为 HTTPResponse 的一部分从服务器呈现时,这实际上有效,但当这样的图像只是作为 .css 文件的一部分包含时则无效。在这种情况下,我会得到:

Failed to load resource: the server responded with a status of 403 (Forbidden)

(我发现如果我复制并粘贴有问题的图片链接并将 &amp; 替换为 &,那么我就可以访问了,这又是一个谜。)

这是我配置 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","Principal": {
                "AWS": "*"
            },"Action": "s3:Getobject","Resource": "arn:aws:s3:::mybucket/static/*"
        }
    ]
}

如何解决此问题以使某些文件(如 static/ 中的所有文件)未签名和公开,但其他文件已签名和私有?

解决方法

如果您查看django-storages的源代码,您会看到一个未记录的类,名为S3StaticStorage强>:

class S3StaticStorage(S3Boto3Storage):
    """Querystring auth must be disabled so that url() returns a consistent output."""
    querystring_auth = False

从这个子类化应该可以解决你的问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?