2015-09-08 95 views
4

我正在尋找一種方式來任何文件類型的原始文件數據和任何可能的內容傳輸中發送原始文件數據(我的意思是所有的用戶生成的文件和文件的內容)這兩種方式都是在Backbone前端對Django後端使用xhr/ajax調用。存儲和JSON對象


編輯:也許這個問題目前還不清楚......

如果您在IDE(如卓異)打開一個文件,你可以查看和編輯實際代碼,包括文件。我試圖把的原始內容放到JSON中,這樣我就可以發送到瀏覽器,它可以被修改,然後發送回去。

我張貼了這個問題,因爲我的印象是,,因爲這些文件的內容,可以有效地在任何編碼語言,只是字符串化-ING的內容並把它發送似乎就像一個脆弱的解決方案,這將是容易打破或利用。內容可以包含任意數量的'"{}字符這似乎打破JSON格式,並逃避這些字符將離開代碼中的文物,將有效地打破他們(不是嗎?)。

如果假設是錯誤的,這也將是一個可以接受的答案(只要你能指出不管是什麼我俯瞰)。


我工作的這個項目是一個基於瀏覽器的IDE將從服務器接收一個完整的文件結構。用戶可以添加/刪除文件,編輯這些文件的內容,然後將其更改保存回服務器。發送/接收都必須通過ajax/xhr調用來處理。

  • 在Backbone中,每個「文件」被實例化爲一個模型並存儲在一個Collection中。該文件的內容將作爲屬性存儲在模型中。
  • 理想情況下,文件內容在更改時仍然可靠地拋出所有適當的事件。
  • 不應將提取內容分解爲與文件模型其餘部分分開的調用。我想只使用單個保存/獲取調用來發送/接收包括原始內容的文件。

需要Underscore/jQuery的解決方案很好,如果有專門用於管理原始文件數據的可用內容,我可以引入其他庫。

+0

Z85執行什麼是問題嗎?你可以很容易地將你的文件存儲爲'{data:'stringyfied_data'}'model –

+1

@LeshaOgonkov - 我的假設(這可能是錯誤的)是,這些文件中不可避免地會有文件類型/格式或內容可能會破壞或利用如果我把所有東西串起來的話。那是錯的嗎?另外,如果將所有可能的任何代碼語言的所有內容串聯起來,而不會修改或破壞這些文件的內容,這將會有多可靠。 – relic

+0

您可以解析和轉義模型數據,取決於您的實現,Backbone只是幫助您將想法存儲在JS –

回答

4

有趣的問題。執行此操作所需的代碼會相當複雜,對不起,我沒有提供示例,但您看起來像一個體面的程序員,應該能夠實現下面提到的內容。

關於通過JSON發送原始數據,您需要做的只是讓JSON安全並且不會破壞您的代碼,就是通過使用Python的json.dumps進行stringyfying轉義特殊字符& JavaScript的JSON.stringyfy。 [1]

如果您擔心某種形式的基本防篡改,那麼您的數據的光編碼將符合目的,除了讓客戶端和服務器來回傳遞每會話令牌使用JSON傳輸來確保JSON不會被惡意地址僞造。

如果要檢查數據的終端到終端的完整,然後生成一個MD5校驗,併發送你的JSON內,然後生成抵達另一個MD5和你的JSON裏面的一個比較。

的Base64編碼:其編碼四個字符代表三個字節數據的數據的大小將由33%增長。

Base85:將四個字節編碼爲五個字符,並將數據增長25%,但在Python中使用比Base64更多的處理開銷。這是數據大小的8%提高,但是以犧牲處理開銷爲代價。它也不是字符串安全的,因爲它使用所有95個可打印的ASCII字符,因此不能在JSON內部使用單引號,尖括號和&符號。&在JSON傳輸之前需要進行stringyfied。 [2]

yEnc只有2-3%的開銷(取決於數據中相同字節的頻率),但排除了不切實際的缺陷(參見[3])。

ZeroMQ Base-85,又名Z85。這是Base85的字符串安全變體,數據開銷爲25%,比Base64更好。將它粘貼到JSON中並不需要stringyfying。我強烈推薦這種編碼算法。 [4] [5] [6]

如果你只發送小文件(比如說幾KB),那麼二進制到文本轉換的開銷是可以接受的。對於大小隻有幾Mbs的文件,讓它們增長25-33%可能是不可接受的。在這種情況下,您可以嘗試在發送前壓縮它們。 [7]

您也可以使用multipart/form-data將數據發送到服務器,但我無法看到這將如何雙向工作。

UPDATE

總之,這裏是我的解決方案的算法:

發送數據

  • 生成會話令牌並在 登錄它存儲相關的用戶(服務器),或從會話cookie(客戶端)檢索

  • 在傳輸期間爲數據生成完整性檢查的MD5散列。

  • 使用Z85對原始數據進行編碼以添加一些基本的防篡改和JSON友好性。

  • 將上面的內容放在JSON中並在請求時發送POST。

接待

  • 抓鬥JSON從POST

  • 檢索會話令牌從存儲的相關用戶(服務器),或從會話cookie(客戶端)檢索。

  • 爲收到的數據生成MD5哈希,並在收到的JSON中針對MD5進行測試,拒絕或有條件地接受。

  • Z85解碼接收到的JSON中的數據以獲取原始數據並根據需要存儲在文件或數據庫(服務器)或進程/顯示在GUI/IDE(客戶端)中。


參考

[1] How to escape special characters in building a JSON string?

[2] Binary Data in JSON String. Something better than Base64

[3] https://en.wikipedia.org/wiki/YEnc

[4] http://rfc.zeromq.org/spec:32

[5]在C/C++ https://github.com/artemkin/z85

[6] Z85 Python實現的https://gist.github.com/minrk/6357188

[7]的JavaScript拉鍊庫http://stuk.github.io/jszip/

[8]的JavaScript Gzip已SO JavaScript implementation of Gzip

+1

夢幻般的回覆。真的很感謝所有的信息。儘管終端的確切實現已經因爲終端的額外需求而變得複雜......所以看起來好像我可能最終得到一個涉及websockets而不是純粹的AJAX的解決方案。在Nelson的帖子後,我已經傾向於使用base64解決方案,但是我不知道您列出的其他編碼方法,甚至沒有想過在整合哈希測試之前提及它。感謝那。 – relic

+1

歡迎您。如果你以不同的方式做,請分享你的解決方案:) –

+1

我對你的解決方案也很感興趣。請分享。 :) –

5

AFAI很關心一個簡單的Base64轉換會做到這一點。將其轉換爲base64,然後將其傳遞給服務器並在那裏解碼。那麼你不會有原始文件傳輸,你仍然會保持你的代碼簡單。

我知道這個解決方案可能顯得有點過於簡單,但仔細想想:許多cryptographics算法可以被打破給予正確的硬件。最安全的方法之一是通過數字證書,然後使用私鑰對數據進行加密,然後將其發送到服務器。但是,爲了達到這種安全級別,您的應用程序的每個用戶都必須擁有一個數字證書,我認爲這對您的用戶而言是過度需求。

所以問問你自己,如果實現一個真正安全的解決方案增添了不少麻煩給你的用戶,你爲什麼需要一個安全轉移呢?基於此,我重申了我之前所說的話。一個簡單的Base64轉換就可以做到。你也可以使用一些其他的算法,比如SHA256,這樣可以讓它變得更加安全。

+2

'安全'絕對比可靠性和速度要低。這些文件中不應該包含任何個人信息,並且已經制定了限制措施來限制惡意代碼的影響。 – relic

+0

是的......我同意。 –

4

如果這裏唯一擔心的是,你的代碼文件(「數據」的模型存儲)的原始內容會導致一些問題的類型存儲在JSON的時候,這是很容易通過逃避數據availed 。

將您的原始代碼文件內容進行字符串化會導致問題,因爲類似於JavaScript或JSON的任何內容都將被解析爲實際的JSON對象。 您的代碼文件數據可以並應該簡單地存儲爲esacaped字符串。這裏你的擔心是,所說的字符串可能包含可能會破壞被存儲在JavaScript中的字符,這可以通過轉義整個字符串來緩解,從而避免了代碼文件中已經轉義的任何東西,從而避免了雙重,三重,四重等等。

在本質上這裏要記住,在一個文件中的原始代碼,不過是一個榮耀的字符串存儲在數據庫中時,除非你是在網上元數據動態地添加是非常重要的。它只是文本,並且執行標準轉義將使它安全地以任何格式存儲爲JSON中的字符串(在「」或「'中)。

我建議你閱讀本SO回答,因爲我也引用它來驗證我已經認爲是正確的: How To Escape a JSON string containing newline characters using JavaScript

+0

我不確定我是否確信它像逃跑一樣簡單,甚至可以對它進行多次逃逸。我將如何自動化一個決定進行多少次測試和轉義的字符的過程(因爲寫入文件的實際語言實際上是未知的)?那麼,我將如何將該過程傳達給前端(在傳輸完成之後)以正確解析文件並確保內容中不會留下任何偏離的字符?我想一個「解碼」鍵可以附加到每個數據模型... – relic

+0

你只需要逃避一次。 –

+0

你還試過嗎? –