【问题标题】:Access denied to css file that is public on S3 AWS bucket拒绝访问在 S3 AWS 存储桶上公开的 css 文件
【发布时间】:2022-01-26 16:13:32
【问题描述】:

所以我有一个 Django 应用程序在 AWS EC2 上的 docker 容器上运行。静态内容托管在 S3 存储桶(css、javascript 等)上。这一切都很好。

我确实使用 weasy print 为某些文件实现了 PDF 输出。在本地,它可以生成预期的 PDF。但是在服务器上,我收到 500 错误。经过仔细检查,我添加到我的装饰器(负责生成 PDF)的 django 日志中弹出以下错误。装饰器装饰一些被调用的句柄,生成的 PDF 显示在下载文件夹中。

装饰处理程序:

@generate_pdf_httpresponse
def handler_warehouse_packingslip(request, **kwargs):
    id = kwargs.get("pk")                                   
    context = { .... details to provide to print.... }
    filename = "foo.pdf"
    infos = {"context":context, "template_path":'projectlibs/pdf_outputs/pdf_base.html', "extra_css_files":[], "filename":filename,"request":request}
    return infos

装饰者:

def generate_pdf_httpresponse(func):
    @functools.wraps(func)
    def wrapper_generate_pdf_httpresponse(*args, **kwargs):

        try:
            logger.info(f"Wrapper for pdf response")
            value = func(*args, **kwargs)
            html_string = render_to_string(value.get("template_path"), context=value["context"])
            html = HTML(string=html_string, base_url=value["request"].build_absolute_uri())
            css_files = []
            pdf = html.write_pdf(stylesheets=css_files)
            logger.info(f"Creating tmp file for pdf response")
            with tempfile.NamedTemporaryFile() as file:
                file.write(pdf)
                file.seek(0)
                stream = file.read()
            httpresponse = HttpResponse(content_type='application/pdf;', content=stream)
            httpresponse['Content-Disposition'] = f'attachment; filename={value["filename"]}'
            httpresponse['Content-Transfer-Encoding'] = 'binary'
            return httpresponse
        except Exception as ex:
            logger.error(f"PDF wrapper failed: {ex}")
    return wrapper_generate_pdf_httpresponse

产生此错误(在 aws 上):

27/12/21 14:03:43 INFO DEFAULT: Wrapper for pdf response
27/12/21 14:03:43 INFO DEFAULT: Request to print packing skips warehouse.... 
27/12/21 14:03:43 ERROR DEFAULT: PDF wrapper failed: Attempted access to '/css/pdf2.css' denied.

但该文件是公开的 - 我可以直接从网络 (https://.s3.amazonaws.com/static/css/pdf2.css) 访问它。我使用的主要样式表也在那里可用,由相同的标签引用并且工作正常。

例如这工作正常:

<link rel="stylesheet" type="text/css" href="{% static 'css/mystyle.css' %}">

但不是这个:

<link href="{% static '/css/pdf2.css'  %}" rel="stylesheet" type="text/css" >

所以....我应该在哪里/如何解决这个问题?

已检查:

  • pdf2.css 存在于静态 s3 存储桶下(访问被拒绝,而不是未找到)
  • 如果我更改从模板引用的 css 文件(用于创建 pdf),我也会被拒绝。所以似乎我的应用程序试图从装饰器访问 css 是导致问题的原因,不知何故。

【问题讨论】:

    标签: django amazon-web-services amazon-s3 weasyprint


    【解决方案1】:

    所以,我还没有设法找到最初问题的实际答案(有人写了一条评论,大意是在 pdf 案例中,css 文件不是从 S3 存储桶中提供的,但我没有完全明白他的意思,他删除了评论)。

    然而,一个有效的改变是替换模板内的 css 链接,并将其转移到 weasy-print。从上面的代码:

    from django.conf import settings
    css_files =  [ f"{settings.STATICFILES_DIRS[0]}/css/pdf2.css"]
    

    假设在 settings.py 中正确设置了 STATICFILES_DIRS

    然后删除&lt;link href="{% static '/css/pdf2.css' %}" rel="stylesheet" type="text/css" &gt;

    然后,因为 weasy print 在本地获取实际文件(例如,从 EC2 实例,在其静态文件夹下),所以它可以工作。我想因为这也是从同一个管道(例如 collectstatic 等)致力于 git,所以从 devops 的角度来看,这是一个不错的解决方案,不需要特殊情况下的步骤/配置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-04
      • 2019-02-03
      • 2019-02-25
      • 2021-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多