在Rails中屏蔽图像的真实URL

时间:2015-05-22 23:54:04

标签: mysql ruby-on-rails ruby image

我在Rails中创建一个非常基本的照片共享应用程序,显示来自本地文件系统的相册。

例如 -

/path/to/pictures
  |
  |-> 2003_college_graduation
  |-> 2002_miami_spring_break

但是,任何人都可以查看HTML源代码并获取图像的绝对路径 -

my.server.com/path/to/pictures/2003_college_graduation/IMG_0001.JPG

通过一些猜测,任何人都可以导航到服务器上的其他图像,即使是他们没有获得许可的图像。

有没有办法去掩饰"这里的URL?

一个可能的解决方案是将每个文件路径散列为UUID并将映射存储在mysql表中。然后,当他们使用该哈希请求URL时,我可以在表中查找并拉出正确的图像。但是这会使URL看起来很乱并且如果URL发生变化会产生问题(因为哈希值会发生变化)。

是否有任何库或其他解决方法来掩盖文件的真实路径?

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用网址缩小器(选择)并使用该链接。如果他们遵循原始来源,他们仍然可以看到原始来源,但它会从html文件中获取。

答案 1 :(得分:1)

你在这里想要实现的是通过默默无闻的安全保障,最终无法实现。人们可以了解来自任何其他来源的混乱网址,并且仍然可以访问他不应该看到的图片。

真正的解决方案是实际控制对文件的访问。这是一个非常常见的问题,有一个很常见的解决方案。为了强制访问控制,您必须在提供文件和验证凭据之前调用Rails控制器操作,然后,如果凭据有效,则提供实际文件。

在控制器中可能是这样的:

<db:stored-procedure config-ref="Oracle_Configuration1" doc:name="Database">
            <db:parameterized-query><![CDATA[{call apps.create_sales_Order(:p_header_rec_oper,:P_order_number,:P_ordered_date,:P_line_id,:p_flow_Status_code,:P_return_status)}]]></db:parameterized-query>
            <db:in-param name="p_header_rec_oper" value="CREATE"/>
            <db:out-param name="P_order_number" type="INTEGER"/>
            <db:out-param name="P_ordered_date" type="DATE"/>
            <db:out-param name="P_line_id" type="VARCHAR"/>
            <db:out-param name="p_flow_Status_code" type="VARCHAR"/>
            <db:out-param name="P_return_status" type="VARCHAR"/>
            
</db:stored-procedure>

然后在你的路线文件中:

class PhotoController < ApplicationController
  def photo
    if user_has_access?(params[:album], params[:photo])
      # be *very* careful here to ensure that user_has_access? really validates
      # album and photo access, otherwise, there's a chance of you letting a malicious
      # user to get any file from your system by feeding in certain params[:album]
      # and params[:photo]
      send_file(File.join('/path/to/albums', params[:album], "#{params[:photo]}.jpg"), type: 'image/jpeg', disposition: 'inline')
    else
      render(file: File.join(Rails.root, 'public/403.html'), status: 403, layout: false)
    end
  end

  private

  def user_has_access?(album, photo)
    # validate that the current user has access and return true, if he does,
    # and false if not
  end
end

然后在你的观点中:

get '/photos/:album/:photo.jpg' => 'photo#photo', as: album_photo

<%= image_tag album_photo_path('album', 'photo') %> 的好处在于它只是在开发模式下从Rails中提供文件,但在生产中,它可以配置为将其卸载到实际的Web服务器,以保持Rails代码的性能最佳。 / p>

希望能够提供一个基本概念,并帮助我们做些什么!