2015-05-22 62 views
0

我在Rails中創建了一個令人難以置信的基本照片共享應用程序,該應用程序顯示來自本地文件系統的相冊。在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會看起來很亂並會產生問題。

是否有任何庫或其他解決方法來屏蔽文件的真實路徑?

謝謝!

+0

谷歌的緩存可能會給你這個。但是你會將圖像存儲在(網頁)根目錄文件夾之外,對吧? – Strawberry

回答

1

你可以使用url minifier(選擇你的選擇)並使用該鏈接。如果他們遵循它們,他們仍然能夠看到原始來源,但它會將其從HTML文件中取出。

1

你試圖在這裏實現的是一種通過默默無聞的安全性,最終不會起作用。人們可以知道來自其他來源的亂碼網址,仍然可以訪問他不應該看到的圖片。

真正的解決方案是實際控制對文件的訪問。這是一個非常常見的解決方案,這是一個很常見的問題爲了強制訪問控制,您必須在提供文件並驗證憑據之前調用Rails控制器操作,然後如果憑據有效,則爲實際文件提供服務。

這可能是這樣的控制器:

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') %> 

什麼好的send_file是它只是在開發模式下從Rails提供文件,但在生產中它可以n被配置爲將其卸載到實際的Web服務器,以保持Rails代碼的性能最佳。

希望給出一個基本的想法,它可能是什麼,有所幫助!