'可疑操作:尝试访问""否认'在加载静态文件时

时间:2017-04-20 21:06:35

标签: django heroku amazon-s3

我已经通过ringer使用Amazon s3在Heroku上设置我的Django app设置来托管静态和媒体文件。我一直在关注这个指南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管理面板中获取它,那么我认为这不是一个桶政策问题,我已经搞砸了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.

settings.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部分有些东西,但我不知道:/

1 个答案:

答案 0 :(得分:7)

排序!正如预期的那样,这是一件非常简单的事情,但也许这将有助于其他任何打同一面墙的人。

此:

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

需要这样:

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

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