python - AWS S3 存储桶 Django 3.0 用户配置文件图像上传访问错误

标签 python django amazon-web-services amazon-s3 django-3.0

简介

  • 我正在关注 this推荐的指南,这里是 guide's GitHub repo .
  • 我也为它创建了一个 AmazonS3FullAccess
  • 我正在使用指南的第三个示例“ 混合公共(public) Assets 和私有(private) Assets ”与静态、媒体公共(public)、媒体、私有(private)版本。
  • 如果用户登录(本地开发环境),他从网站上传文件,但他不能仅从 AWS S3 管理网站从网站访问它们。
  • 目前我阻止了指南中的所有公共(public)访问(AWS S3 管理面板设置)
  • 我已将这些行添加到我的 CORS 配置编辑器 来自 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>
    
  • 打开对我来说更本地化的中央欧盟服务器。没有工作我得到了同样的错误。

  • 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
    

    设置.py
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'MYPROJECTS_MAIN_APP/static'),]
    
    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"
    

    模型.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')
    

    View .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)
    

    错误
    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>
    

    到目前为止我尝试过的东西
  • 它创建了 AWS 链接并将文件添加到本地“媒体”文件夹中。但是由于我删除了“媒体文件夹”并且它只创建了 URL 链接,并且实际上将它们上传到 S3 存储桶
  • 我发现了相同的 question在 aws 论坛上,但尚未得到答复
  • 访问权限 Django + AWS S3 Bucket: Authenticated Access to S3 Bucket (我不明白这个答案 https://stackoverflow.com/a/21614550/10270590)
  • “使用 AWS4-HMAC-SHA256”
  • 将 S3 主机的区域指定为正确的用法 https://github.com/aws/aws-sdk-js/issues/829
  • 查找您所在地区的站点 - https://docs.aws.amazon.com/general/latest/gr/rande.html
  • 我也收到了这个建议“大多数新区域仅支持 AWS4-HMAC-SHA256 - 如果您的代码不支持此身份验证方案并且仅创建“v2 签名”,请在旧区域之一(例如欧洲)创建您的存储桶成为唯一的爱尔兰 - 在这里查看:https://docs.aws.amazon.com/general/latest/gr/signature-version-2.html
  • 我在 欧盟与我的测试机 - 我建立了一个美国基地 S3 存储桶 - 我如何配置 Django 应用程序或 AWS S3 存储桶,以便它可以从任何地方访问它(特别重要的是部署该应用程序以便世界各地的人们都可以访问它)。来自同一个男人 video's评论区评论了以下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
  • 这是我添加到设置中的确切代码 based on除了原始指南的代码之外。当我切换图像时,它可以工作,但是当我离开配置文件设置并返回时,图像消失并给出原始错误):
  • AWS_S3_HOST = "s3.eu-central-1.amazonaws.com"
    S3_USE_SIGV4 = True
    AWS_S3_REGION_NAME = "eu-central-1"
    
  • 关闭所有访问限制(临时)并将存储桶策略添加到 AWS S3 管理控制台
  • 1 代码:{ "Version":"2012-10-17", "Statement":[{ "Sid":"PublicReadGetObject", "Effect":"Allow", "Principal": "", "Action":["s3:GetObject"], "Resource":["arn:aws:s3:::myprojectname_that_jsut_abow_this_field/*" ] } ] } --> 错误
  • 2 代码:{ "Version":"2012-10-17", "Statement":[{ "Sid":"PublicReadGetObject", "Effect":"Allow", "Principal": "", "Action":["s3:GetObject"], "Resource":["arn:aws:s3:::myprojectname_that_jsut_abow_this_field/" ] } ] }/* --> 错误
  • 3 CODE:我改成这个了{ "Version":"2012-10-17", "Statement":[{ "Sid":"PublicReadGetObject", "Effect":"Allow", "Principal": "*", "Action":["s3:GetObject"], "Resource":"arn:aws:s3:::myprojectname_that_jsut_abow_this_field/*" } ] }并得到以下错误:Error Access denied
  • 4 代码:{ "Version":"2012-10-17", "Statement":[{ "Sid":"PublicReadGetObject", "Effect":"Allow", "Principal": "", "Action":["s3:GetObject"], "Resource":"arn:aws:s3:::myprojectname_that_jsut_abow_this_field/*" } ] }错误:Error Missing required field Principal cannot be empty!
  • 最佳答案

    在 AWS 控制台中,单击“权限”选项卡,然后单击

  • 允许公开访问您的存储桶 -> 保存 -> 确认
  • “存储桶策略”按钮。将出现一个编辑框。将编辑框中的“arn:aws:s3:::”替换为编辑框上方显示的以“arn:”开头的部分,但请注意保留末尾的“/*”。使用下面的代码。粘贴以下内容:
  •  {
      "Version":"2012-10-17",
      "Statement":[{
        "Sid":"PublicReadGetObject",
            "Effect":"Allow",
          "Principal": "*",
          "Action":["s3:GetObject"],
          "Resource":["arn:aws:s3:::your-buckt-arn/*"
          ]
        }
      ]
    }
    

    关于python - AWS S3 存储桶 Django 3.0 用户配置文件图像上传访问错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61322805/

    相关文章:

    python - 变音符号

    amazon-web-services - Terraform:AWS Cloudfront 分布在将 Terraform 状态后端从本地更改为 s3 后给出 CNAMEAlreadyExists 错误

    python - 使用 OS X automator 在 csv 文件上运行 Python 脚本

    django - 在django模板中获取用户信息

    python - 如何比较不同标签的 pandas dataframe 对象中的值?

    python - 我无法决定是使用外键、多对多字段还是选择字段

    django - 将 websockets 集成到 Django Rest Framework 应用程序的简单方法?

    amazon-web-services - 在 API Gateway 或 lambda 中将一些信息保存为 session

    python - 如何将非线性模型转换为线性模型?

    python - pandas DataFrame 的 transform 与 applymap 之间有什么区别