2009-07-24 96 views
1

我將添加文件上傳控制到我的ASP.NET 2.0網頁,以便用戶可以上傳文件。文件將存儲在服務器中的文件夾中,其名稱與用戶相同。我想知道保存到服務器時命名文件的最佳選擇是什麼。需要考慮安全性,性能,靈活性來處理文件等。如果我錯過了什麼,請指導我文件上傳:應該保存的文件名稱是什麼?

選項我正在考慮現在:

  1. 上傳具有相同名稱的輸入文件名的
  2. 添加用戶ID +隨機數字+文件名稱作爲輸入文件名稱
  3. 創建隨機數+當前時間(以秒爲單位)並保存具有該數字的文件。將有一個表格將此號碼與用戶上傳地圖

還有其他什麼?什麼是最好的方法?

預先感謝

回答

5

永遠不要用戶輸入的文件名。不要使用用戶名。用戶的用戶名,而不是(我假設你的用戶有一個唯一的ID)。

從不使用原始文件名。使用您的解決方案編號3,加上用戶名,而不是用戶名。

有關您的信息,幾年前PHP有一個漏洞:可以僞造一個帶有文件上傳的HTTP POST請求,並帶有文件名如「../../anything.php」,以及php應該包含淨化值的_FILES數組沒有檢測到這些類型的文件名,所以可以在文件系統中的任何地方寫入文件。

+0

你能解釋一下爲什麼? – Treb 2009-07-24 08:50:21

+2

因爲我可以上傳一些php代碼,並且如果將它以.php擴展名保存在您的服務器上,那麼它將在我訪問它時執行。 有很多例子,當允許使用任意名稱的文件上傳時,很難想到所有訪問服務器的方法,這就是爲什麼最好不要讓任意名稱放在首位。 – FWH 2009-07-24 08:58:20

0

我會選擇#3。將這些文件與用戶進行映射的表格將提供其他用途,但總是如此。如果您使用映射,則將用戶名或id附加到文件的唯一好處是如果您嘗試調試問題。

我可能會使用一個GUID而不是一個隨機數,但要麼工作。在我看來,最重要的事情是

  1. 沒有用戶名作爲文件名的一部分作爲存儲的文件
  2. 不要使用原始文件名保存的文件
  3. 使用隨機數的任何部分的任何部分或GUID,以確保沒有重複的文件
  4. 添加一個用戶ID文件將與手動調試幫助發出
0

還有更多的這比滿足眼睛......我在想,你已經知道了!

你在說什麼類型的文件?如果它們的大小甚至遠大於文件組的大小,我會立即建議你爲你的方法增加一些靈活性。

  1. 創建一個表存儲根路徑到各種文件存儲(這可能是驅動器,unc路徑,您的環境支持)。它最初將有一個條目,這將是您的第一個存儲位置。用這些數據維護一個很好的屬性是可以在這裏存儲多少空間。
  2. 維護一個文件相關數據表(id {guid},創建日期,外鍵到路徑數據,文件大小)
  3. 將文件寫入仍然有空間的根目錄(查詢存儲在根位置並與根容量進行比較)
  4. 使用名稱的GUID寫入文件(模糊文件系統上的文件)..如果安全要求它可以寫入文件擴展名(敏感文件)
  5. 根據創建日期從根/年開始編寫文件{number}/month {number}/day {number} /file.extension

使用這種性質的系統 - 即使您不會預先需要它 - 現在您可以更輕鬆地重定位文件。你可以更好地管理這些文件。您可以更好地管理文件集合。等我以前使用過這個系統,發現它非常靈活。處理存儲到文件系統但從數據庫管理的文件可能會在文件存儲變得如此龐大以及需要移動一些東西時變得有點失控。另外,至少在windows的情況下......將文件存儲在一個目錄中通常不是一個好主意(通過創建日期來分解文件的原因)。

只有當您擁有大容量和大尺寸的腳印時,才需要這種複雜性。

2

我會使用的組合

  • 用戶ID
  • 一個隨機生成的字符串(例如,GUID)

例PDF文件名:23212-dd503cf8-a548-4584- a0a3-39dc8be618df.pdf

這樣,用戶就可以上傳他/她想要的任意多個文件,而不會發生文件名衝突,並且您還能夠指出哪些文件屬於哪些用戶,只需l以文件名稱打開。

我沒有看到需要在文件名中包含任何其他信息,因爲上傳時間/日期等可以從文件的屬性中檢索。

此外,您應該將文件存儲在安全位置,外部用戶(例如您的網站的訪問者)無法訪問。而是通過代理網頁將文件傳遞給他們(您從安全位置讀取文件並將數據傳遞給用戶)。對於此解決方案,需要數據庫來跟蹤文件及其位置等。

這也使您能夠控制哪些用戶可以通過您的代碼訪問哪些文件。


更新:這裏有一個如何與代理網頁的解決方案可以實現的描述。

  1. 名爲GetFile.aspx
  2. GetFile.aspx接受名爲fileid一個查詢參數,它是用來標識文件,以獲得創建Web窗體。例如。:
    http://www.mypage.com/GetFile.aspx?fileid=100
  3. 使用fileid參數來查找數據庫中的文件位置,以便它可以被讀取併發送給用戶。在Web窗體中,您使用Request.QueryString("fileid")來獲取文件ID並將其用於看起來像這樣的查詢(SQL):
    SELECT FileLocation FROM UserFiles WHERE FileID = 100
  4. 使用System.IO.FileStream讀取文件並通過Response.Write輸出其內容。請記得先使用首先設置合適的,以便客戶端瀏覽器正確處理請求的文件(請參閱asp.forums.net上的this post和文章中也提到的MDSN article,它們都討論了自動確定適當內容類型的方法) 。

如果選擇此方法,稍後可以輕鬆實現自己的簡單安全性或自定義操作,例如確保用戶在發送文件之前登錄到您的網站,或者用戶只能訪問文件上傳他們自己,或者用戶下載哪些文件記錄等的可能性是無窮無盡;-)

1

看看在System.IO.Path class,因爲它有很多的,你可以利用有用的功能,如:

檢查文件名中哪些字符無效:

System.IO.Path.GetInvalidPathChars(); 

得到一個隨機文件名:

System.IO.Path.GetRandomFileName(); 

獲得一個獨特的,randome名在臨時目錄

System.IO.Path.GetTempFileName(); 
相關問題