標籤:

Web API介面如何防止本網站/APP以外的調用?

Web API介面如何防止本網站/APP以外的調用?

現在APP的API是WEB API實現的,返回的數據是JSON格式。

現在有個問題就是如何防止本APP或者本網站以外的地方調用這些API。

比如說,現在有一個新聞列表的介面,返回新聞標題的JSON數據。如果別人也知道了這個API地址,那麼對方也可以拿去使用,這樣對我們的伺服器就會造成不必要的壓力。

需要在伺服器和客戶端做哪些工作才能解決上述問題呢?


如果你的api對正常的客戶端或瀏覽器開放,那麼是沒有辦法完全阻止別人模擬該客戶端來調用你的web api的。你只能做限制。

1. 要求登錄驗證。

2. 每個登錄的session做限流,比如限制每分鐘內的api調用次數。ip或帳號級別也做限流。

3. 通過api調用模式偵測出異常用戶。


這個一般意義上來說就是防盜鏈是吧。簡單提一些方法,從介面的設計開始。

1. HTTPS。首先介面建議使用 HTTPS 協議,這樣至少會給破解者在抓包的時候提高一些難度。上面也有答主提到其它協議,實現起來有難度不說,實際上也沒有這個必要吧;

2. 介面參數的設置。這個很重要,有必要設置一些驗證參數。這裡面有兩種常見的做法。

  • MD5 校檢值形式。設置一個 sign 參數,這個參數是一個 MD5 值,其原文是請求的其它參數和一些固定的加密字元串(鹽)的組合。我更建議再加上一個時間 tm 參數,可以是當前的時間戳,把這個 tm 參數也融合到 sign 裡面去,樂視網的很多介面和視頻地址就是採用的此形式。

int id = 10000; // 假設請求的參數為 id ,假設為 10000
int tm = System.currentTimeMillis() / 1000;
String sign = md5(id + tm + "salt"); // md5 是實現取 md5 值(32 位元組的 Hex 文本)的函數,salt 是加密鹽,建議修改長一點。
String api = "https://www.xxx.com/api?id=" + id + "tm=" + tm + "sign=" + sign;
// 請求 API

  • 演算法加密字元串形式。和上面的 MD5 差不多,只不過是把參數用 AES / DES 之類的對稱或者非對稱演算法加密之後作為一個驗證參數。伺服器接到請求之後,解密參數,看看是否正確。這裡面還可以加入一些客戶端的本地信息作為判斷依據。優酷和騰訊視頻就是採用的此形式。

3. 本地加密混淆。上面第 2 點提到的驗證參數,不建議直接放到本地代碼裡面。不管是 Android 裡面的 Java 代碼,還是 Flash 裡面的 AS 代碼,都非常容易被反編譯,非常簡單就可以看到源代碼。所以要放到獨立的模塊中去。優酷土豆、騰訊視頻等,都是使用的此技術。

  • 對於 Android 程序,我建議把加密的部分放到 so (C 動態庫)文件中去,這樣的話破解者即使想破解,也得用上反彙編工具。對 so 文件,兩個建議:函數結構要混淆,函數名要混淆,入口點不要用默認的;so 文件要做驗證!一定要做驗證,否則破解者根本不用破解,直接拿你的 so 文件去使用,你就相當於直接給他寫好盜鏈模塊了…
  • 對於 Flash,建議使用 FlasCC(Alchemy)技術,將 C 模塊植入,這比上面的 so 文件更難破解,打開過很多 Alchemy 技術的 Flash 文件,頭都大了。

4.伺服器端簡單限制。在 Web API 的伺服器端也有必要做一些簡單的限制。

  • User-Agent 和 Referer 限制。限制這些作用不大,但能有效地防止 Web 端直接盜鏈。除非對方實現了 Socket,但有這個技術的話,何必還來盜鏈你呢~
  • 驗證登錄。這裡所說登錄不一定是賬戶登錄,還可以是設備 device 登錄。可以給用戶設備分配一個唯一的 device id,用來驗證。這些信息可以放在 Cookie 里,也可以直接作為一個參數。
  • 請求頻次限制。對單個 device id 可以設置其請求頻率,device id 很容易偽造,所以建議伺服器生成,本地只記錄和傳遞。另外上面有些答主提到了 IP 頻率限制。我不建議對 IP 進行太多的限制,如果限制頻率太低,這會影響正常用戶使用,因為國內運營商環境複雜,很多用戶共用一個出口 IP 的現象非常常見。但也千萬別因此就相信了 HTTP Header 中的 X-Forwarded-For,這個參數是可以直接偽造的。
  • 返回的結果可以加密。然後客戶端在本地進行解密,解密的代碼最好也放到 so 文件中去。

5. 定期檢查訪問日誌。上面提到,不建議對 IP 進行限制,那怎麼辦呢?請務必定期檢查伺服器的訪問日誌,這樣可以很容易篩選、排查出異常 IP。找出異常流量的 IP 之後,上網搜索一些這些 IP,判斷是不是有伺服器在盜鏈,然後 ban 掉它們(其實一開始就可以先找到阿里雲、百度雲、新浪雲等雲廠商的 IP 範圍,先把他們屏蔽)。

最後,要是對方完全破解了你的防盜鏈措施,並且在客戶端完全模擬你客戶端的行為的話。那我還能說什麼呢…只能說你的產品非常有價值。


1.app請求數據要加密;

2.網頁web api請求考慮使用加密token;

3.結合1,2。你已經知道哪些是非法請求。記錄下來對應訪問標記,攔截之即可。


我的解決辦法是, 用戶安裝app時會 隨機從伺服器 返回 一個 token, 以後用戶每次請求伺服器數據 必須帶上這個token 和uuid。

服務端 檢測這個token連續 三次 每分鐘請求異常,就重新給他發一個token, 如果重新發token超過三次。 就讓他輸個驗證碼,再次請求token。

這樣 正常用戶 不會受到干擾。

而非正常用戶 大規模抓取數據 只能用幾次就的重新輸驗證碼,要不重新下載app。 我相信他也不在折騰了。


這是無法做到的

只能有一些防護方法

1 一定要有簽名參數,並保護好籤名演算法

2 使用https

3 對單IP以及客戶端加入調用限制


個人覺得

你在伺服器端和允許訪問的客戶端設置primary key和public key,然後生成定時變更的token值,每次訪問必須驗證這個值不就好了。感覺這是最直接也比較簡單的方法。

或者設置登錄驗證也可以,每次都必須驗證用戶身份。


如果是被業務後端調用,試試:

ip限制

用戶身份認證

如果要開放給瀏覽器端

沒轍了。。。


1、APP和伺服器介面先約定好一個密鑰;

2、登錄之後伺服器介面返回一個Token;

3、APP在之後需要驗證的請求中都要加上這個Token,以及進行簽名。


公網上跑的wepapi,又要限制別人訪問本身就是悖論。你只能訪問許可權,但是被人知道客戶端調用的密鑰,他就無所不能了。


身份驗證,驗證碼,


要麼傳輸數據做加密處理,要麼就做身份驗證,其他暫時不知道……


添加一個HTTP頭部驗證信息吧,只有符合要求的請求才可以通過驗證,可以參考一下百度翻譯API的做法


1.https

2.身份認證

3.介面及參數名稱故意混淆

4.不定期更換介面二級域名


http 1,服務端獲取ip搞定。2,密碼串訪問


推薦閱讀:

如何才能寫出簡潔好看的API文檔,有沒有開源框架可以用?
SDK和API的區別?
網站後台要做客戶端API介面,介面文檔如何寫?
有沒有開源的api管理系統?
知乎將如何做開放?

TAG:API |