保命貼!老司機教你如何應對比女朋友的小心思還要多的設計

好吧,各位看官老爺們,有點標題狗了,這篇主要講的的是,我們日常經常使用的 API 接口設計

當然我們在內網使用的 API 接口可以適當放鬆一些規範涉及,但是涉及到對外網訪問請求的時候,我們就需要考慮比較多的問題了,譬如:

  • API 接口應該如何設計?
  • API 接口應該如何保證安全?
  • API 接口應該如何設置簽名?
  • API 接口必要的時候如何進行防重?

以上問題是我們在對外提供 API 的時候所必須要考慮的。

如何設計也就是說 API 接口需要做哪些,需不需要安全校驗,需不需要防重,需不需要高併發等等

保證安全也就是說不讓髒數據請求進來

設置簽名也是爲了防止髒數據

防重是爲了保證數據的唯一性

1. API 接口應該如何保證安全?

這裏我們一般會使用 token + appId + secreteKey + timestamp

在這裏插入圖片描述
圖示是一種請求方式的流程圖,其實無論什麼情況,目的就是爲了不讓外網隨便什麼參數都能訪問,儘量保證數據的整潔性和完整性

Token: 訪問令牌access token,用於接口中,用於標識接口調用者的身份、憑證,減少用戶名和密碼的傳輸次數。一般情況下調用方調用前已經向服務方拿到了對應的密鑰,也就是說服務方會給出一個 appId 和一個 secreteKey,secreteKey 用於參數簽名使用,使服務方能夠確認調用者。

注意key保存到客戶端,需要做一些安全處理,防止泄露。

服務方返回的 Token 值一般是UUID,服務端生成Token後需要將token做爲key,將一些和token關聯的信息作爲value保存到緩存服務器中(redis),當一個請求過來後,服務器就去緩存服務器中查詢這個Token是否存在,存在則調用接口,不存在返回接口錯誤,一般通過攔截器或者過濾器來實現,Token分爲兩種:

API Token(接口令牌): 用於訪問不需要用戶登錄的接口,如登錄、註冊、一些基本數據的獲取等。獲取接口令牌需要拿appId、timestamp和sign來換,sign=加密(timestamp+key)
USER Token(用戶令牌):用於訪問需要用戶登錄之後的接口,如:獲取我的基本信息、保存、修改、刪除等操作。獲取用戶令牌需要拿用戶名和密碼來換

關於Token的時效性:token可以是一次性的、也可以在一段時間範圍內是有效的,具體使用哪種看業務需要

其實當我們不使用token 直接使用 appId + secreteKey + timestamp + sign 也是可以的

2. timestamp 簡介

timestamp: 時間戳,是客戶端調用接口時對應的當前時間戳,時間戳用於防止DoS攻擊。

當黑客劫持了請求的url去DoS攻擊,每次調用接口時接口都會判斷服務器當前系統時間和接口中傳的的timestamp的差值,如果這個差值超過某個設置的時間(假如5分鐘),那麼這個請求將被攔截掉,如果在設置的超時時間範圍內,是不能阻止DoS攻擊的。timestamp機制只能減輕DoS攻擊的時間,縮短攻擊時間。如果黑客修改了時間戳的值可通過sign簽名機制來處理。

3. sign 簡介

sign:一般用於參數簽名,防止參數被非法篡改,最常見的是修改金額等重要敏感參數。

sign的值一般是將所有非空參數按照升續排序然後+token+key+timestamp拼接在一起,然後使用某種加密算法進行加密,作爲接口中的一個參數來傳遞,也可以將sign放到請求頭中。

服務方拿到參數,會根據固定的加密方法將給到的參數加密算出 sign 和 調用方的 sign 進行比較,如果一致說明是正常請求,否則不予處理。

增加sign 的目的主要是爲了防止接口在網絡傳輸過程中如果被黑客挾持,並修改其中的參數值,然後再繼續調用接口,產生的錯誤數據

增加簽名校驗的話,雖然參數的值被修改了,但是因爲黑客大概率無法知道sign的計算方式,也不知道夠成 sign 中最重要的secreteKey是什麼,所以即便黑客可以篡改參數的值,但服務方根據篡改後的參數,按照規則重新計算出sign 和 調用方給到 sign 是無法匹配的,就不會執行接口

4、防止重複提交

對於一些重要的操作需要防止客戶端重複提交的(如非冪等性重要操作),具體辦法是當請求第一次提交時將 sign 作爲key保存到redis,並設置超時時間,超時時間爲 調用方給到的 Timestamp + 固定時間。如果服務方對於 token 的處理是存儲固定的時間,那麼 token 的存儲時間和 sign 的存儲時間一致

當同一個請求第二次訪問時會先檢測redis是否存在該sign,如果存在則證明重複提交了,接口就不再繼續調用了。

如果sign在緩存服務器中因過期時間到了,而被刪除了,此時當這個url再次請求服務器時,因token的過期時間和sign的過期時間一直,sign過期也意味着token過期,那樣同樣的url再訪問服務器會因token錯誤會被攔截掉,這就是爲什麼sign和token的過期時間要保持一致的原因。拒絕重複調用機制確保URL被別人截獲了也無法使用(如抓取數據)。

對於哪些接口需要防止重複提交可以自定義個註解來標記。

注意:所有的安全措施都用上的話有時候難免太過複雜,在實際項目中需要根據自身情況作出裁剪,比如可以只使用簽名機制就可以保證信息不會被篡改,或者定向提供服務的時候只用Token機制就可以了。如何裁剪,全看項目實際情況和對接口安全性的要求。

拓展:

DoS

DoS是Denial of Service的簡稱,即拒絕服務,造成DoS的攻擊行爲被稱爲DoS攻擊,其目的是使計算機或網絡無法提供正常的服務。最常見的DoS攻擊有計算機網絡帶寬攻擊和連通性攻擊。

DoS攻擊是指故意的攻擊網絡協議實現的缺陷或直接通過野蠻手段殘忍地耗盡被攻擊對象的資源,目的是讓目標計算機或網絡無法提供正常的服務或資源訪問,使目標系統服務系統停止響應甚至崩潰,而在此攻擊中並不包括侵入目標服務器或目標網絡設備。這些服務資源包括網絡帶寬,文件系統空間容量,開放的進程或者允許的連接。這種攻擊會導致資源的匱乏,無論計算機的處理速度多快、內存容量多大、網絡帶寬的速度多快都無法避免這種攻擊帶來的後果。

  • Pingflood: 該攻擊在短時間內向目的主機發送大量ping包,造成網絡堵塞或主機資源耗盡。
  • Synflood: 該攻擊以多個隨機的源主機地址向目的主機發送SYN包,而在收到目的主機的SYN ACK後並不迴應,這樣,目的主機就爲這些源主機建立了大量的連接隊列,而且由於沒有收到ACK一直維護着這些隊列,造成了資源的大量消耗而不能向正常請求提供服務。
  • Smurf:該攻擊向一個子網的廣播地址發一個帶有特定請求(如ICMP迴應請求)的包,並且將源地址僞裝成想要攻擊的主機地址。子網上所有主機都回應廣播包請求而向被攻擊主機發包,使該主機受到攻擊。
  • Land-based:攻擊者將一個包的源地址和目的地址都設置爲目標主機的地址,然後將該包通過IP欺騙的方式發送給被攻擊主機,這種包可以造成被攻擊主機因試圖與自己建立連接而陷入死循環,從而很大程度地降低了系統性能。
  • Ping of Death:根據TCP/IP的規範,一個包的長度最大爲65536字節。儘管一個包的長度不能超過65536字節,但是一個包分成的多個片段的疊加卻能做到。當一個主機收到了長度大於65536字節的包時,就是受到了Ping of Death攻擊,該攻擊會造成主機的宕機。
  • Teardrop:IP數據包在網絡傳遞時,數據包可以分成更小的片段。攻擊者可以通過發送兩段(或者更多)數據包來實現TearDrop攻擊。第一個包的偏移量爲0,長度爲N,第二個包的偏移量小於N。爲了合併這些數據段,TCP/IP堆棧會分配超乎尋常的巨大資源,從而造成系統資源的缺乏甚至機器的重新啓動。
  • PingSweep:使用ICMP Echo輪詢多個主機。

參考:https://mp.weixin.qq.com/s/oJ_0kIKytFOMe7b5-UTgaw

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章