Cloudfront CORS 问题在 Rails 应用程序上提供字体

2024-03-03

访问我的网站时,我不断从控制台收到此错误消息:

font from origin 'https://xxx.cloudfront.net' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.example.com' is therefore not allowed access.

我已经尝试了一切:

  • 我已经安装了字体资产宝石 https://github.com/ericallam/font_assets
  • 配置application.rb文件

    config.font_assets.origin = 'http://example.com'
    
  • Cloudfront 上的白名单标头,如中所述本文 http://kennethjiang.blogspot.co.uk/2014/07/set-up-cors-in-cloudfront-for-custom.html to

    Access-Control-Allow-Origin
    Access-Control-Allow-Methods
    Access-Control-Allow-Headers
    Access-Control-Max-Age
    

但什么也没有,零,什么也没有。

我在 Heroku 上使用 Rails 4.1。


这是一个非常难以处理的问题,原因有二:

  1. CloudFront 的事实是镜像我们的 Rails 应用程序的响应标头需要您充分思考。 CORS 协议本身就很难理解,但现在您必须在两个级别上遵循它:浏览器和 CloudFront 之间(当我们的 Rails 应用程序将其用作 CDN 时),以及浏览器和我们的 Rails 应用程序之间(当一些恶意网站想要滥用我们)。

    CORS 实际上是浏览器与网页想要访问的第三方资源之间的对话。 (在我们的用例中,这是 CloudFront CDN,为我们的应用程序提供资产。)但是由于 CloudFront 获取其访问控制响应标头from我们的应用程序,我们的应用程序需要提供这些标头as if这是 CloudFront 正在说话,并且同时地不授予可能导致自身遭受滥用的权限,而正是这种滥用导致了同源策略/CORS 的开发。特别是,我们不应该授予*进入*我们网站上的资源。

  2. I found so much那里有过时的信息——无穷无尽的博客文章和SO线程。自发布许多帖子以来,CloudFront 已显着改进了其 CORS 支持,尽管它仍然不完美。 (CORS 确实应该开箱即用地处理。)宝石本身已经进化了。

我的设置:Rails 4.1.15 在 Heroku 上运行,资产由 CloudFront 提供。我的应用程序在“www”上响应 http 和 https。和区域顶点,不做任何重定向。

我简单地浏览了问题中提到的 font_assets gem,但很快就放弃了它,转而使用rack-cors,这似乎更切题。我不想简单地开放所有来源和所有路径,因为这会破坏 CORS 的要点和同源策略的安全性,因此我需要能够指定我允许的少数来源。最后,我个人更喜欢通过个人配置 Railsconfig/initializers/*.rb文件而不是编辑标准配置文件(例如config.ru or config/application.rb)将所有这些放在一起,这是我的解决方案,我认为这是截至 2016 年 4 月 16 日为止最好的解决方案:

  1. Gemfile

    gem "rack-cors"
    

    rack-cors gem 在 Rack 中间件中实现 CORS 协议。 除了在批准的来源上设置 Access-Control-Allow-Origin 和相关标头之外,它还添加了Vary: Origin响应标头,指示 CloudFront 分别缓存每个源的响应(包括响应标头)。当我们的网站可通过多个来源访问时(例如通过 http 和 https,以及通过“www.”和裸域),这一点至关重要

  2. 配置/初始化器/rack-cors.rb

    ## Configure Rack CORS Middleware, so that CloudFront can serve our assets.
    ## See https://github.com/cyu/rack-cors
    
    if defined? Rack::Cors
        Rails.configuration.middleware.insert_before 0, Rack::Cors do
            allow do
                origins %w[
                    https://example.com
                     http://example.com
                    https://www.example.com
                     http://www.example.com
                    https://example-staging.herokuapp.com
                     http://example-staging.herokuapp.com
                ]
                resource '/assets/*'
            end
        end
    end
    

    这告诉浏览器它只能代表我们的 Rails 应用程序(并且通过扩展,在 CloudFront 上,因为它是我们的镜像)访问我们的 Rails 应用程序上的资源(并且not代表恶意站点.com)且仅用于/assets/网址(和not对于我们的控制器)。换句话说,允许 CloudFront 为资产提供服务,但不要打开任何不必要的门。

    Notes:

    • 我尝试插入这个after机架超时而不是在中间件链的头部。 它在开发中有效,但在 Heroku 上不起作用,尽管 具有相同的中间件(Honeybadger 除外)。
    • 来源列表也可以作为正则表达式完成。 小心地将图案锚定在绳子末端。

      origins [
          /\Ahttps?:\/\/(www\.)?example\.com\z/,
          /\Ahttps?:\/\/example-staging\.herokuapp\.com\z/
      ]
      

      但我认为读取文字字符串更容易。

  3. 配置 CloudFront 以将浏览器的 Origin 请求标头传递到我们的 Rails 应用程序。

    奇怪的是,CloudFront 似乎将 Origin 标头从浏览器转发到我们的 Rails 应用程序不管我们是否将其添加到此处,但 CloudFront 尊重我们应用程序的Vary: Origin仅当 Origin 明确添加到标头白名单(截至 2016 年 4 月)时才使用缓存指令。

    请求标头白名单有点被隐藏了。

    如果该发行版已经存在,您可以在以下位置找到它:

    • https://console.aws.amazon.com/cloudfront/home#distributions https://console.aws.amazon.com/cloudfront/home#distributions
    • 选择分布
    • 单击分发设置
    • 转到行为选项卡
    • 选择行为(可能只有一个)
    • 单击编辑
    • 转发标头:白名单
    • 白名单标头: Select Origin然后单击添加>>


    如果您尚未创建发行版,请在以下位置创建:

    • https://console.aws.amazon.com/cloudfront/home#distributions https://console.aws.amazon.com/cloudfront/home#distributions
    • 单击创建分配

      (为了完整性和可重复性,我列出了我从默认值更改的所有设置,但是白名单设置是唯一与此讨论相关的设置)

    • 交付方式:Web(非 RTMP)

    • 原点设置

      • 源域名:example.com
      • Origin SSL 协议:仅限 TLSv1.2
      • 源协议策略:仅限 HTTPS
    • 默认缓存行为设置

      • 查看器协议策略:将 HTTP 重定向到 HTTPS
      • 转发标头:白名单
      • 白名单标头: Select Origin然后单击添加>>
      • 自动压缩对象:是

更改所有这些内容后,请记住,任何旧的缓存值可能需要一段时间才能从 CloudFront 过期。您可以通过转至 CloudFront 发行版的“失效”选项卡并为以下内容创建失效来显式使缓存资产失效:*.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cloudfront CORS 问题在 Rails 应用程序上提供字体 的相关文章

  • 2015 年重新审视 Ember Handling 401

    我可以在 Ember Ember Data 中找到大量询问 回答如何从 Rails 后端处理 401 的老问题 许多 如果不是全部的话 在这一点上似乎已经过时了 我已经尝试了我能找到的一切 Ember 数据处理 401 https stac
  • Watir 脚本偶尔返回 Net::ReadTimeout 错误

    我有一个 Watir 脚本 偶尔会意外地返回此错误 Net ReadTimeout 我搜索了这个错误并发现这个问题 https stackoverflow com questions 47452276 watir get sometimes
  • Ruby on Rails:simple_form + Twitter Bootstrap 未显示

    我正在为我的网站上的新用户创建一个简单的注册表单 我已经运行了 simple form bootstrap 的安装 rails g simple form install bootstrap 但是 它仍然没有显示并呈现为正常的 simple
  • 从 Facebook 重定向 URL 中删除“#_=_”[重复]

    这个问题在这里已经有答案了 根据https developers facebook com blog post 552 https developers facebook com blog post 552 FB Graph API 现在附
  • 无法使用 docker-compose 在 Dockerfile 中运行 rake db:create

    我有一个Dockerfile and docker compose yml就像在tutorial https docs docker com compose rails 除非我从现有的应用程序开始 My docker compose yml
  • Uber API 不允许来自本地主机的请求

    当我使用 Uber API 和 localhost 时 我收到以下错误 请求的资源上不存在 Access Control Allow Origin 标头 起源 http 本地主机 8080 http localhost 8080 因此不允许
  • Rails 3.2 开发模式不显示带有回溯等的完整错误页面

    我刚刚升级到 Rails 3 2 一切正常 除了错误页面不再显示正常的开发调试信息 相反 它显示标准生产错误页面 白色背景 中间有红色文本 很抱歉 出了点问题 我们已收到有关此问题的通知 我们会尽快查看 Rails 3 2 是否有新的设置或
  • 从架构中删除表 - Rails

    我想删除架构中的一个表 我在第一次启动项目时创建了数据库并希望删除该表 这样做的最佳方法是什么 I tried rails g migration drop table installs但这只会创建一个空迁移 Schema create t
  • 向 Rails 应用程序中的内置类添加方法

    我想向 Rails 应用程序中的 Array 类添加一个方法 我应该把这个方法放在哪里 编辑得更清楚 显然我把它放在某个文件中 但是我如何告诉 Rails 应用程序在哪里可以找到它 执行此操作的一种方法是在以下位置创建一个文件lib rai
  • Django ValueError:缺少静态文件清单条目,但清单似乎显示该条目

    在部署到 Heroku 的 Django 1 11 应用程序上 加载根 URL 时 我猜当 Django 到达时 static angular angular min js in the homepage html模板 我收到以下错误 Va
  • 查询参数和assert_generates/assert_routing - 我缺少什么?

    我想我已经介绍了使用查询参数测试路由的排列 但没有一种方法通过 在我的 paths rb 中 我有以下内容 resources items 然后对于我的功能测试我有 require ruby debug require test helpe
  • 如何设置管理员批准模型的编辑

    我需要一个普通用户可以编辑模型的系统 但编辑实际上只有在管理员批准后才会发生 我发现了一颗宝石 叫做纸迹 https github com airblade paper trail它确实有模型版本控制 但不具体支持我想要做的事情 我想知道其
  • NoMethodError 未定义方法“名称” for nil:NilClass

    我有两个模型帖子和类别 我试图在我的索引和帖子显示视图中显示每个帖子的类别名称 我正在使用表连接 但问题是 虽然在我的显示视图中类别显示正确 但它在索引视图中给出了 NoMethodError undefined method name f
  • RubyMine 不能使用 Guard 吗?

    由于某些无法解释的原因 RubyMine 会自动保存您所做的每一个更改 因此每次击键都会触发 Guard 运行您的测试 最可笑的是 显然没有办法禁用这个自动保存 功能 我只是想知道 RubyMine 似乎是 Rails 开发人员中非常流行的
  • Rails 3.1 和 Asset Pipeline:使用 Capistrano 进行部署时遇到的问题

    我刚刚从 Ruby on Rails 3 0 10 切换到 3 1 0 我想使用 Capistrano gem 部署我的资产文件 我的本地计算机是运行 Snow Leopard 的 MacO 我的远程计算机运行的是 Ubuntu 10 04
  • 如何使用 rspec 测试 ActionCable 和 Devise?

    在我的 Rails 5 1 应用程序中 我使用设备进行身份验证和 ActionCable 我的 ActionCable 连接如下所示 module ApplicationCable class Connection lt ActionCab
  • 从字符串名称返回 FontStyle

    我想编写一个函数 它将返回 FontStyle 并以字符串作为参数 FontStyle f function Italic FontStyles Italic 我不想编写 Switch case 或 if else 语句来执行相同的操作 对
  • SQL where 连接集必须包含所有值,但可以包含更多值

    我有三张桌子offers sports和连接表offers sports class Offer lt ActiveRecord Base has and belongs to many sports end class Sport lt
  • 同一模型之间的两个 has_many 链接

    I have users其中有products通过 habtm 链接 该链接正在运行 我想添加一个链接user模型和product模型 以跟踪creator该产品的 当然 谁并不总是拥有该产品 但是当我写在我的user and produc
  • 强参数不起作用

    使用 Ruby 1 9 3 Rails 3 2 13 Strong parameters 0 2 1 我遵循了教程和railscasts中的每一个指示 但我无法让strong parameters工作 这应该是非常简单的事情 但我看不出错误

随机推荐