仅为安全页面保护回形针网址

Sha*_*moe 11 https ruby-on-rails paperclip secure-scl

我正在努力找到使回形针网址安全的最佳方法,但仅限于安全页面.

例如,显示存储在S3中的图像的主页是http://mydomain.com,图像URL是http://s3.amazonaws.com/mydomainphotos/89/thisimage.JPG?1284314856.

我有像https://mydomain.com/users/my_stuff/49这样的安全页面,其中的图像存储在S3中,但S3协议是http而不是https,因此用户会从浏览器收到一条警告,说明某些元素在页面不安全,等等等等.

我知道我可以在模型中指定:s3_protocol,但这使得一切都安全,即使没有必要.所以,我正在寻找将协议更改为https的最佳方法,仅用于安全页面.

一种(可能是坏的)方法是创建一个新的url方法,如:

def custom_url(style = default_style, ssl = false)
  ssl ? self.url(style).gsub('http', 'https') : self.url(style)
end
Run Code Online (Sandbox Code Playgroud)

需要注意的一点是,我正在使用ssl_requirement插件,因此可能有一种方法可以将其与之相关联.

我确信有一些简单,标准的方法可以做到这一点,我忽略了,但我似乎无法找到它.

emr*_*ass 17

如果有人现在偶然发现:自20124月起,Paperclip就有了解决方案!只需写:

Paperclip::Attachment.default_options[:s3_protocol] = ""
Run Code Online (Sandbox Code Playgroud)

在初始化程序中或使用s3_protocol模型中的选项.

感谢@Thomas Watson发起这个.


Tho*_*son 7

如果使用Rails 2.3.x或更高版本,您可以使用Rails中间件过滤响应,然后再将其发送回用户.这样,您可以检测当前请求是否为HTTPS请求,并相应地修改对s3.amazonaws.com的调用.

创建一个名为的新文件paperclip_s3_url_rewriter.rb,并将其放在服务器启动时加载的目录中.该libdirecotry将工作,但许多人宁愿创建一个app/middleware目录,然后将其添加到Rails应用程序负载路径.

将以下类添加到新文件:

class PaperclipS3UrlRewriter
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    if response.is_a?(ActionController::Response) && response.request.protocol == 'https://' && headers["Content-Type"].include?("text/html")
      body = response.body.gsub('http://s3.amazonaws.com', 'https://s3.amazonaws.com')
      headers["Content-Length"] = body.length.to_s
      [status, headers, body]
    else
      [status, headers, response]
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

然后只需注册新的中间件:

Rails 2.3.x:将以下行添加到Rails::Initializer.run块开头的environment.rb中.
Rails 3.x:将以下行添加到Application类开头的application.rb中.

config.middleware.use "PaperclipS3UrlRewriter"
Run Code Online (Sandbox Code Playgroud)

更新:
我刚刚编辑了我的答案,并response.is_a?(ActionController::Response)在if语句中添加了一个检查.在某些情况下(可能与缓存相关),响应对象是一个空数组(?),因此在request调用它时会失败.

更新2: 我编辑了上面的机架/中间件代码示例以更新Content-Length标头.否则大多数浏览器都会截断HTML正文.

  • 将S3 url-rewriter注入到应用程序所服务的每个请求中而不是封装逻辑以生成正确的URL似乎是不幸的. (3认同)