iOS架構(gòu)學(xué)習(xí)篇——接口的設(shè)計

App與服務(wù)器的通信接口如何設(shè)計得好,需要考慮的地方挺多的,在此根據(jù)我的一些經(jīng)驗做一些總結(jié)分享,旨在拋磚引玉。

安全機制的設(shè)計

現(xiàn)在,大部分App的接口都采用RESTful架構(gòu),RESTFul最重要的一個設(shè)計原則就是,客戶端與服務(wù)器的交互在請求之間是無狀態(tài)的,也就是說,當(dāng)涉及到用戶狀態(tài)時,每次請求都要帶上身份驗證信息。實現(xiàn)上,大部分都采用token的認證方式,一般流程是:

用戶用密碼登錄成功后,服務(wù)器返回token給客戶端;

客戶端將token保存在本地,發(fā)起后續(xù)的相關(guān)請求時,將token發(fā)回給服務(wù)器;

服務(wù)器檢查token的有效性,有效則返回數(shù)據(jù),若無效,分兩種情況:

token錯誤,這時需要用戶重新登錄,獲取正確的token

token過期,這時客戶端需要再發(fā)起一次認證請求,獲取新的token

然而,此種驗證方式存在一個安全性問題:當(dāng)?shù)卿浗涌诒唤俪謺r,黑客就獲取到了用戶密碼和token,后續(xù)則可以對該用戶做任何事情了。用戶只有修改密碼才能奪回控制權(quán)。

如何優(yōu)化呢?第一種解決方案是采用HTTPS。HTTPS在HTTP的基礎(chǔ)上添加了SSL安全協(xié)議,自動對數(shù)據(jù)進行了壓縮加密,在一定程序可以防止監(jiān)聽、防止劫持、防止重發(fā),安全性可以提高很多。不過,SSL也不是絕對安全的,也存在被劫持的可能。另外,服務(wù)器對HTTPS的配置相對有點復(fù)雜,還需要到CA申請證書,而且一般還是收費的。而且,HTTPS效率也比較低。一般,只有安全要求比較高的系統(tǒng)才會采用HTTPS,比如銀行。而大部分對安全要求沒那么高的App還是采用HTTP的方式。

我們目前的做法是給每個接口都添加簽名。給客戶端分配一個密鑰,每次請求接口時,將密鑰和所有參數(shù)組合成源串,根據(jù)簽名算法生成簽名值,發(fā)送請求時將簽名一起發(fā)送給服務(wù)器驗證。類似的實現(xiàn)可參考OAuth1.0的簽名算法。這樣,黑客不知道密鑰,不知道簽名算法,就算攔截到登錄接口,后續(xù)請求也無法成功操作。不過,因為簽名算法比較麻煩,而且容易出錯,只適合對內(nèi)的接口。如果你們的接口屬于開放的API,則不太適合這種簽名認證的方式了,建議還是使用OAuth2.0的認證機制。

我們也給每個端分配一個appKey,比如Android、iOS、微信三端,每個端分別分配一個appKey和一個密鑰。沒有傳appKey的請求將報錯,傳錯了appKey的請求也將報錯。這樣,安全性方面又加多了一層防御,同時也方便對不同端做一些不同的處理策略。

另外,現(xiàn)在越來越多App取消了密碼登錄,而采用手機號+短信驗證碼的登錄方式,我在當(dāng)前的項目中也采用了這種登錄方式。這種登錄方式有幾種好處:

不需要注冊,不需要修改密碼,也不需要因為忘記密碼而重置密碼的操作了;

用戶不再需要記住密碼了,也不怕密碼泄露的問題了;

相對于密碼登錄其安全性明顯提高了。

接口數(shù)據(jù)的設(shè)計

接口的數(shù)據(jù)一般都采用JSON格式進行傳輸,不過,需要注意的是,JSON的值只有六種數(shù)據(jù)類型:

Number:整數(shù)或浮點數(shù)

String:字符串

Boolean:true 或 false

Array:數(shù)組包含在方括號[]中

Object:對象包含在大括號{}中

Null:空類型

所以,傳輸?shù)臄?shù)據(jù)類型不能超過這六種數(shù)據(jù)類型。以前,我們曾經(jīng)試過傳輸Date類型,它會轉(zhuǎn)為類似于"2016年1月7日 09時17分42秒 GMT+08:00"這樣的字符串,這在轉(zhuǎn)換時會產(chǎn)生問題,不同的解析庫解析方式可能不同,有的可能會轉(zhuǎn)亂,有的可能直接異常了。要避免出錯,必須做特殊處理,自己手動去做解析。為了根除這種問題,最好的解決方案是用毫秒數(shù)表示日期。

另外,以前的項目中還出現(xiàn)過字符串的"true"和"false",或者字符串的數(shù)字,甚至還出現(xiàn)過字符串的"null",導(dǎo)致解析錯誤,尤其是"null",導(dǎo)致App奔潰,后來查了好久才查出來是該問題導(dǎo)致的。這都是因為服務(wù)端對數(shù)據(jù)沒處理好,導(dǎo)致有些數(shù)據(jù)轉(zhuǎn)為了字符串。所以,在客戶端,也不能完全信任服務(wù)端傳回的數(shù)據(jù)都是對的,需要對所有異常情況都做相應(yīng)處理。

服務(wù)器返回的數(shù)據(jù)結(jié)構(gòu),一般為:

{code:0,message:"success",data:{key1:value1,key2:value2,...}}

code: 返回碼,0表示成功,非0表示各種不同的錯誤

message: 描述信息,成功時為"success",錯誤時則是錯誤信息

data: 成功時返回的數(shù)據(jù),類型為對象或數(shù)組

不同錯誤需要定義不同的返回碼,屬于客戶端的錯誤和服務(wù)端的錯誤也要區(qū)分,比如1XX表示客戶端的錯誤,2XX表示服務(wù)端的錯誤。這里舉幾個例子:

0:成功

100:請求錯誤

101:缺少appKey

102:缺少簽名

103:缺少參數(shù)

200:服務(wù)器出錯

201:服務(wù)不可用

202:服務(wù)器正在重啟

錯誤信息一般有兩種用途:一是客戶端開發(fā)人員調(diào)試時看具體是什么錯誤;二是作為App錯誤提示直接展示給用戶看。主要還是作為App錯誤提示,直接展示給用戶看的。所以,大部分都是簡短的提示信息。

data字段只在請求成功時才會有數(shù)據(jù)返回的。數(shù)據(jù)類型限定為對象或數(shù)組,當(dāng)請求需要的數(shù)據(jù)為單個對象時則傳回對象,當(dāng)請求需要的數(shù)據(jù)是列表時,則為某個對象的數(shù)組。這里需要注意的就是,不要將data傳入字符串或數(shù)字,即使請求需要的數(shù)據(jù)只有一個,比如token,那返回的data應(yīng)該為:

//正確data:{token:123456}//錯誤data:123456

接口版本的設(shè)計

接口不可能一成不變,在不停迭代中,總會發(fā)生變化。接口的變化一般會有幾種:

數(shù)據(jù)的變化,比如增加了舊版本不支持的數(shù)據(jù)類型

參數(shù)的變化,比如新增了參數(shù)

接口的廢棄,不再使用該接口了

為了適應(yīng)這些變化,必須得做接口版本的設(shè)計。實現(xiàn)上,一般有兩種做法:

每個接口有各自的版本,一般為接口添加個version的參數(shù)。

整個接口系統(tǒng)有統(tǒng)一的版本,一般在URL中添加版本號,比如http://api.domain.com/v2。

大部分情況下會采用第一種方式,當(dāng)某一個接口有變動時,在這個接口上疊加版本號,并兼容舊版本。App的新版本開發(fā)傳參時則將傳入新版本的version。

如果整個接口系統(tǒng)的根基都發(fā)生變動的話,比如微博API,從OAuth1.0升級到OAuth2.0,整個API都進行了升級。

有時候,一個接口的變動還會影響到其他接口,但做的時候不一定能發(fā)現(xiàn)。因此,最好還要有一套完善的測試機制保證每次接口變更都能測試到所有相關(guān)層面。

寫在最后

關(guān)于接口設(shè)計,暫時想到的就這么多了。各位看官看完覺得有遺漏或有哪些需要優(yōu)化的歡迎提出一起討論。

PS:于2016-04-18

之前code我解釋為狀態(tài)碼,可能導(dǎo)致有些人將其和request status code混為一談,因此改為了返回碼,其含義其實和以下地址中的微信公眾平臺的返回碼是一樣的。

http://mp.weixin.qq.com/wiki/10/6380dc743053a91c544ffd2b7c959166.html





原創(chuàng)文章,轉(zhuǎn)載請注明:轉(zhuǎn)載自Keegan小鋼

原文鏈接:http://keeganlee.me/post/architecture/20160214

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 12,308評論 6 13
  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中。。。 其實如果沒有APIManager這一層是沒法使用delegate的,畢竟多個單...
    yhtang閱讀 5,466評論 1 23
  • App架構(gòu)設(shè)計經(jīng)驗談:技術(shù)選型 App架構(gòu)設(shè)計經(jīng)驗談:接口的設(shè)計 App架構(gòu)設(shè)計經(jīng)驗談:數(shù)據(jù)層的設(shè)計 App架構(gòu)設(shè)...
    前進的碼農(nóng)閱讀 4,491評論 0 8
  • 原文出處:Keegan小鋼 App與服務(wù)器的通信接口如何設(shè)計得好,需要考慮的地方挺多的,在此根據(jù)我的一些經(jīng)驗做一些...
    yuditxj閱讀 346評論 0 8

友情鏈接更多精彩內(nèi)容