django - '可疑操作: Attempted access to "" denied' while loading static files

标签 django heroku amazon-s3

我已经通过使用 Amazon s3 在 Heroku 上设置我的 Django 应用程序来托管静态和媒体文件。我一直在关注本指南 https://www.caktusgroup.com/blog/2014/11/10/Using-Amazon-S3-to-store-your-Django-sites-static-and-media-files/以及似乎有数千种其他资源的东西,collectstatic 已经工作,heroku 正在部署它 - 但显示 400 错误。当我尝试在本地运行它时,我得到了更多信息:

Attempted access to '/css/reset.css' denied.

这是突出显示的行:
<link rel="stylesheet" type="text/css" href="{% static '/css/reset.css' %}">

如果我从我的 s3 管理面板中抓取静态文件,我可以直接从 URL 加载静态文件,所以我认为这不是存储桶策略问题,我弄乱了 https/http 选项,但没有任何乐趣。所以我认为它一定是在代码中以某种方式调用了错误的路径 - 我只是看不到哪里!

非常感谢任何帮助,我认为我已经连续 4 个小时没有眨眼了。

追溯:
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/storages/backends/s3boto.py" in _normalize_name
  358.             return safe_join(self.location, name)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/storages/backends/s3boto.py" in safe_join
  59.         raise ValueError('the joined path is located outside of the base path'

During handling of the above exception (the joined path is located outside of the base path component), another exception occurred:

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/devtop/webdev/projects/intro/intro/profiles/views.py" in index
  14.     return render(request, 'home.html', {'welcome':welcome})

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/shortcuts.py" in render
  30.     content = loader.render_to_string(template_name, context, request, using=using)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/loader.py" in render_to_string
  68.     return template.render(context, request)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/backends/django.py" in render
  66.             return self.template.render(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render
  207.                     return self._render(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in _render
  199.         return self.nodelist.render(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/loader_tags.py" in render
  177.             return compiled_parent._render(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in _render
  199.         return self.nodelist.render(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/templatetags/static.py" in render
  105.         url = self.url(context)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/templatetags/static.py" in url
  102.         return self.handle_simple(path)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/templatetags/static.py" in handle_simple
  117.             return staticfiles_storage.url(path)

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/storages/backends/s3boto.py" in url
  487.         name = self._normalize_name(self._clean_name(name))

File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/storages/backends/s3boto.py" in _normalize_name
  361.                                       name)

Exception Type: SuspiciousOperation at /
Exception Value: Attempted access to '/css/reset.css' denied.

设置.py
AWS_ACCESS_KEY_ID=os.environ.get('AWS_ACCESS_KEY_ID',None)
AWS_SECRET_KEY=os.environ.get('AWS_SECRET_KEY',None)
AWS_SECRET_ACCESS_KEY=os.environ.get('AWS_SECRET_KEY', None)
AWS_STORAGE_BUCKET_NAME = 'intro-story'
AWS_S3_HOST='s3.us-east-2.amazonaws.com'
AWS_S3_CUSTOM_DOMAIN = 's3.us-east-2.amazonaws.com/%s' % AWS_STORAGE_BUCKET_NAME

AWS_S3_SECURE_URLS = False

STATICFILES_LOCATION = 'static'
STATICFILES_STORAGE = 'custom_storages.StaticStorage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)

MEDIAFILES_LOCATION = 'media'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'


try:
    from .local_settings import *
except ImportError:
    pass

local_settings.py
AWS_ACCESS_KEY_ID = "xxx"
AWS_SECRET_ACCESS_KEY = "yyy"

custom_storages.py
from django.conf import settings
from storages.backends.s3boto import S3BotoStorage

class StaticStorage(S3BotoStorage):
    location = settings.STATICFILES_LOCATION

class MediaStorage(S3BotoStorage):
    location = settings.MEDIAFILES_LOCATION

编辑:

我设法通过处理 settings.py 中的各种值来使其工作,但仍然不对。

这是与静态和媒体路径相关的所有内容
STATICFILES_LOCATION = 'static'
MEDIAFILES_LOCATION = 'media'

import custom_storages

STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)
STATICFILES_STORAGE = 'custom_storages.StaticStorage'

MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'

这是我要导入的 custom_storage:
from django.conf import settings
from storages.backends.s3boto import S3BotoStorage

class StaticStorage(S3BotoStorage):
    location = settings.STATICFILES_LOCATION

class MediaStorage(S3BotoStorage):
    location = settings.MEDIAFILES_LOCATION

现在,如果我注释掉
STATICFILES_STORAGE = 'custom_storages.StaticStorage'

它将从 S3 加载静态文件,一切正常,但 collectstatic 失败。如果我取消注释该行,collectstatic 会起作用,但是当我尝试加载站点时会出现错误。错误是:
 # Ensure final_path starts with base_path and that the next character after
    # the final path is '/' (or nothing, in which case final_path must be
    # equal to base_path).
    base_path_len = len(base_path)
    if (not final_path.startswith(base_path) or
            final_path[base_path_len:base_path_len + 1] not in ('', '/')):
        raise ValueError('the joined path is located outside of the base path' ...
                         ' component')
    return final_path.lstrip('/')

很明显,custom_storage 部分出了点问题,但我不知道是什么:/

最佳答案

排序!正如预期的那样,这是一件令人讨厌的简单事情,但也许这会帮助其他遇到同一堵墙的人。

这个:

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

需要是这样的:
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">

IE。 href 中没有前导斜杠。使用本地静态文件存储工作正常,但破坏了 S3 链接。

关于django - '可疑操作: Attempted access to "" denied' while loading static files,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43529912/

相关文章:

java - 如何将 Java Web 应用程序迁移到 Heroku

ruby-on-rails - Heroku 安装 app sushi ,将数据库推送到 Heroku

azure - 使用凭据在 Hive 上为 Azure Blob 创建外部表

java - 如何正确设置 S3 和 IAM 以将文件上传到 S3 存储桶?

python - 无法使用 Django Rest 框架发送压缩的 gzip 数据

django 测试客户端获取 404,但浏览器工作

mysql - Django:用户错误的外键

python - 为什么 Django 迁移在每一行上使用相同的随机默认值?

redirect - Heroku/GoDaddy : send naked domain to www

amazon-web-services - AWS Lambda 在 S3 存储桶中创建文件夹