2010-10-30 34 views
16

我喜歡谷歌地圖的API被消耗的方式,使用腳本包括,但我很擔心:如何設計一個允許安全跨域腳本的JavaScript API?

我的API是‘半私’,就是通過互聯網訪問,但應該允許安全傳輸數據和某種認證。數據應該保持私密性,並且一個消費者不應該能夠獲取他人的數據。

如何使用SSL和某種身份驗證來保持數據安全,但仍然可以從純HTML頁面「橫向」訪問而不需要服務器端代理?我需要管理密鑰嗎?如何將密鑰發佈到服務器而不被攔截?我可以使用OpenId(或其他第三方認證)來驗證api用戶,還是必須創建我自己的認證機制?我已經遍佈Google,無法找到一個安全設計和部署API的好指南。

現在我正在使用REST和AJAX來使用它們,但跨域調用是不可能的。任何幫助或指針在正確的方向將不勝感激。

+1

一個小問題 - 當客戶端在javascript中時,您如何期望密鑰或密碼是安全的?所有「半隱私」對任何偷看代碼的人都是透明的。 – naugtur 2010-11-09 12:05:51

+0

他可以生成客戶端證書並使用Flash/HTML5本地存儲將其存儲......然後讓網站通過URL或window.name將參數傳遞給iframe,該iframe將使用安全調用中的證書來獲取任何數據要顯示在iframe中(以避免使用cookie或登錄過程)。 – dlongley 2010-11-09 16:53:06

+0

@naugtur:這就是我發佈這個問題的原因:) – 2010-11-09 17:46:36

回答

10

我可能會使用帶有SSL URL的動態生成的腳本標記,該URL包含查詢字符串中被公鑰加密的密鑰。服務器將使用私鑰解密查詢字符串參數並返回包含相關信息的腳本(或者,如果密鑰無效)。或類似的規定。但我承認,我實際上並不需要這樣做。

我還會尋找現有技術,如亞馬遜的S3服務。

所以:

  1. 用戶提供祕密
  2. 客戶端代碼使用公鑰加密的祕密
  3. 的JavaScript追加script標籤包含URL
  4. Server處理腳本請求,解密祕密,檢查它併發回相關的響應。

您可能需要兩個週期,否則可能會通過中間人攻擊重新使用對服務器的請求。這將是:

  1. 的JavaScript追加script標籤請求的唯一密鑰(可能有一些混雜的信息,如源IP地址和一些隨機的進一步鍵)
  2. 服務器用綁在一次性密鑰響應該IP
  3. 用戶提供祕密
  4. 客戶端代碼使用公鑰加密的祕密,其中包括來自#1
  5. 的唯一鍵的JavaScript追加script標籤包含URL
  6. 服務器處理腳本請求,解密祕密,檢查它併發回相關響應。使用包含在#1

其中沒有我其實是做了隨機密鑰

  • 的反應很可能被加密(在某種程度上)。 (或者我有?BWAa-ha-ha-ha ...) FWIW。

  • 0

    OAuth可能通過讓用戶登錄到第三方應用程序並允許您的應用程序在您進行xhr請求時通過使用請求令牌來訪問第三方來幫助解決這種情況。 http://oauth.net/documentation/getting-started/

    ========

    之所以使用服務器端代理歸結爲內置網絡瀏覽器相同的起源:http://en.wikipedia.org/wiki/Same_origin_policy

    本質上,瀏覽器只允許請求被製作成頁面來自的地址(例如,facebook.com只能向facebook.com URI發送請求)。服務器端代理通過向當前原點之外的服務器發出請求來解決此問題。服務器端代理也是提出這樣的請求的最佳實踐。

    +0

    我會考慮設置一個服務器端代理,對於只讀數據有點沉重。我想啓用在瀏覽器中執行的安全「mash-ups」。 – 2010-11-08 21:02:22

    0

    查看開源的javascript Forge項目。它提供了一個允許安全的跨域xhr請求的JavaScript TLS實現。這可能是你有幫助:

    http://digitalbazaar.com/2010/07/20/javascript-tls-1/

    http://digitalbazaar.com/2010/07/20/javascript-tls-2/

    https://github.com/digitalbazaar/forge

    一個潛在的解決方案:

    1. 設置Apache服務器來運行你的網站。
    2. 爲您的網站獲取SSL證書。
    3. 安裝Forge附帶的apache mod以設置允許其他站點訪問您的跨域策略。
    4. Host Forge在您的網站上實施TLS以及PEM格式的網站證書。
    5. 告訴其他網站,包括你的網站的JavaScript,並使用它來安全地撥打你的網站去做任何你想做的事情。
    +0

    不知道你的用例有多複雜......但是如果其他站點不需要以任何方式(或不可信)訪問從API返回的數據,那麼只需使用iframe就可以完成工作。 – dlongley 2010-11-08 18:49:28

    0
    1. (第三方)頁使用OAuth或類似對用戶進行認證,並從你的服務器令牌東西。
    2. 頁面從您的服務器通過SSL加載一個IFRAME,並傳遞令牌以進行驗證。
    3. 的IFRAME可以安全地通過SSL
    4. 使用easyXDM或類似的IFRAME和第三方頁面之間進行通信使用的東西,你創造了一些有限的RPC狀或類似插座的API傳達到你的服務器。

    或者,如果你真的不相信第三方 - 在iframe中進行身份驗證(不需要oauth,那麼只需使用一個純html表單)並且傳遞外部頁面需要了解的用戶信息使用easyXDM。

    0

    不太確定這個問題到底是什麼,我認爲你試圖對[https://secure.com]進行類似jsonp的調用來處理/顯示[http:///regular.com]

    兩臺服務器可以相互通話嗎?如何這樣的事情:

    1. 用戶登錄在[https://secure.com]

    2. 在認證時,secure.com生成令牌(讓我們稱之爲它syntoken)並將它直接傳遞到regular.com(服務器到服務器),可能像session_id,一些任意消息和一個otp密碼(讓我們稱之爲syncipher)。

    3. Broswer收到session_id的cookie中,然後Secure.com將瀏覽器重定向到http://regular.com/setcookieandredirect?session_id=blabla&otpencryptedsynmessage=blabla

    4. Regular.com查找使用SESSION_ID作爲一個關鍵的一次一密密碼,並解密otpencryptedmessage 「布拉布拉」。

    5. 如果解密消息與合成信息中的原始消息相匹配,我們可以驗證用戶是否登錄了[regular.com],並且regular.com生成了另一個令牌(讓它稱爲acktoken,lolz),並將其直接傳遞給[secure .com],包含session_id,一些任意的ack消息,以及一個不同的otp密碼(讓我們稱之爲ackcipher)。

    6. Regular.com然後向瀏覽器發送包含otpencryptedackmessage(讓我們將此cookie命名爲「verified_session」)的cookie。

    7. 完成加載頁面。

    從那裏,你可以做JSONP,來電來樣

    https://secure.com/getscript.js?query=dataname&verifiedtoken=(verified_sessions_cookie_value

    其中secure.com/getscript.js將採取verifiedtoken,查找在原有基礎上的cookie SESSION_ID的ackcipher由[secure.com]作爲密鑰發送,並解密otpencrypedack消息。如果解密的消息與確認消息匹配,則呈現腳本文件。

    它有點像3路握手。祕密之處在於服務器必須能夠直接相互交談以分散地傳遞祕密密鑰。您不必爲兩臺服務器使用相同的session_id,我只是將其用作查找訪問syn/ack otp密碼的便捷參考點。密碼必須完全隱藏。

    相關問題