Api項目設計攻略

App全部數據都來源於服務器,App和服務器交互廣泛是採用http請求接口的方式,那麼在搭建和維護一個後端Api項目時候須要注意哪些問題呢?nginx

1. 數據保護

數據保護作的好很差,有兩個原則來驗證:
第一,能夠控制讓誰來讀取數據,
對於任何一個Api項目其實就是隻容許產品App自己訪問,這就須要用密文傳輸請求數據,作到即便被人用抓包工具抓到請求數據也沒有辦法解析出參數的意義。
把安全作到更近一步,能夠在加密以前引入timestamp參數,在服務端經過比較timestamp和當前時間戳能夠作到對於抓取到的連接也不能重複調用。
密文的安全性取決於參數的加密方式,使用對稱加密、非對稱加密或者二者結合取決於團隊本身的選擇,固然若是接口域名已經配了證書支持https,就不用本身寫代碼來作這些事情了。
若是密文傳輸已經作到絕對安全不可破解,那就安全了嗎?固然不是,你要相信安全永遠是相對的。試想一下若是App源碼被反編譯成功,那他就能夠按照代碼邏輯去拼出正常的請求?另一般業務除了有app以外也會有使用相同接口的h5版,任意一個開發者經過瀏覽器的調試模式很容易能分析出請求的Url以及相關參數。對於這兩種狀況怎麼辦呢?sql

第二,對於能夠獲取數據的端,也能夠控制其能夠獲取哪些數據
既然客戶端不能作到徹底可靠,那就讓服務端多承擔一些任務,在app啓動時或者用戶登陸時服務端先向每一個客戶端分發一個有固定有效期的secret,而且在服務端數據庫庫中存儲客戶端惟一標示或者uid和secret的對應關係,以後每次客戶端調用都要用secret對於參數組合進行一次簽名,而且確保參數包含uid,服務端接收到請求後根據uid找出對應的secret,而後按照和客戶端相同的簽名方式得出簽名,進而和客戶端傳過來的簽名進行比較。
由於secret是服務端分發的,即便破解了源碼,再即便從本地解析出了保存的secret,那也只能獲取這個secret對應的數據,再加上secret自己會有更新機制,這就使得經過破解接口來抓取大量數據變得大大的困難。數據庫

可是對於向第三方開放的api接口狀況就不太同樣,它不存在密文傳輸的問題,大致思路也是使用secret進行簽名認證,只是分發secret的方式不同,它是經過合做的方式,api提供商會給使用方分發一個key和一個secret,二者能夠當成一個鍵值對。調用方每次調用時用secret進行參數的簽名,參數包含key,服務端接收到請求,根據key參數取出secret,而後進行相同方式的簽名,而且和客戶端傳入的簽名進行對比來完成驗證。後端

總結一下數據保護的技術點:api

  1. 參數傳輸使用密文,可使用對稱加密、非對稱加密、或者二者的結合,好比https請求就是屬於二者結合的方式。
  2. app端要儘可能加大反編譯的難度,儘可能保護源碼安全。
  3. 經過參數id=>secret的方式進行簽名來進行用戶身份認證,調用方保存本身的secret,服務端保存id和secret的對應關係,secret用於簽名,後續的每次請求都要帶着id參數。
  4. 在第三步的基礎上,加上timestamp參數來防止鏈接重複調用。

2. 安全性

一些經常使用的安全問題都要考慮到,而且在api項目框架底層進行防範,例如xss攻擊、sql注入問題、單用戶或者單ip的訪問頻率控制來進行防cc攻擊。數組

3. 舊版本兼容

互聯網產品版本迭代很快,對於同一個功能新舊版本在參數或者返回值上會有差異。對於這種問題會有不一樣觀點的解決方案,一種方案是在url中加入版本信息,好比http://api.demo.com/v1/test , 每一個版本對應一個Action,具體的業務邏輯不要寫在Action層,要封裝到下面的邏輯層,這樣Action只須要在主業務的基礎上根據需求進行擴展。另一種觀點是,這樣代碼重複度過高,會有大量的action文件,一個功能只提供一個惟一的url,可是要帶上一個表示版本的參數,在代碼框架中只有一個action,對於新舊版本的細小差異可使用參數默認值等兼容方式進行處理,對於比較大的改動就經過邏輯判斷語句進行不一樣處理便可。
另外比較重要的一點是,在設計之初要對業務進行足夠的抽象化,讓設計自己能儘可能支持變化,好比之後此接口是否會增長某個分類屬性,返回結果的格式是否再多包裝一層就能夠應對萬一後面版本要增長另外一塊數據。
固然不可能同時維護全部舊的版本,要作到能夠檢測每一個版本的使用狀況,並且能夠根據版本使客戶端強制升級。對於功能的修改,同時維護舊版本是一件特別麻煩的事情,甚至有些狀況不得不強制升級全部版本。
總結一下就是:瀏覽器

  1. 要能區分不一樣版本,經過url或者參數
  2. 設計時候儘可能考慮以後擴展,足夠抽象化
  3. 支持根據版本進行強制升級

4. 儘量把全部業務邏輯都放到服務端

很容易理解,服務端不用發版,服務端沒有處理不了的問題,很簡單一個例子:用戶登陸功能,會有"密碼錯誤","尚未註冊"等各類異常狀況的提示。那具體的文案是在客戶端定義,仍是從服務端直接返回給客戶端比較好呢,顯然是後者。由於之後提示語內容要作修改的話,放在服務端就能夠很簡單進行處理,放在客戶端只能從新發版。安全

5. 返回字段可定製,可幫用戶節省流量

A、B兩個功能都須要獲取用戶信息,二者調用同一個接口,可是A只須要獲取用戶名和電話,就沒有必要把其它信息返回給A。服務器

6. 格式統一,易讀

  1. uri統一化,不必定說非要用restful格式,但必定要有統一的規範。
  2. 響應結果格式也統一,建議在最外層節點至少包含:code,msg,result,response_time等字段,具體的業務功能數據封裝在result中。
nginx公衆號也會推送好文,主要聊聊後端技術,掃描或者搜索nginx便可添加。
圖片描述
相關文章
相關標籤/搜索