開放接口/RESTful/Api服務的設計和安全方案詳解


一、總體思路

這個涉及到兩個方面問題:
一個是接口訪問認證問題,主要解決誰可以使用接口(用戶登錄驗證、來路驗證)
一個是數據數據傳輸安全,主要解決接口數據被監聽(HTTPS安全傳輸、敏感內容加密、數字簽名)

二、session的狀態保持及弊端
當用戶第一次通過瀏覽器使用用戶名和密碼訪問服務器時,服務器會驗證用戶數據,驗證成功后在服務器端寫入session數據,向客戶端瀏覽器返回sessionid,瀏覽器將sessionid保存在cookie中,當用戶再次訪問服務器時,會攜帶sessionid,服務器會拿着sessionid從數據庫獲取session數據,然后進行用戶信息查詢,查詢到,就會將查詢到的用戶信息返回,從而實現狀態保持。

弊端:

1、服務器壓力增大

通常session是存儲在內存中的,每個用戶通過認證之后都會將session數據保存在服務器的內存中,而當用戶量增大時,服務器的壓力增大。

2、CSRF跨站偽造請求攻擊

session是基於cookie進行用戶識別的, cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊。

3、擴展性不強

如果將來搭建了多個服務器,雖然每個服務器都執行的是同樣的業務邏輯,但是session數據是保存在內存中的(不是共享的),用戶第一次訪問的是服務器1,當用戶再次請求時可能訪問的是另外一台服務器2,服務器2獲取不到session信息,就判定用戶沒有登陸過。

三、token認證機制

token與session的不同主要在

①認證成功后,會對當前用戶數據進行加密,生成一個加密字符串token,返還給客戶端(服務器端並不進行保存)

②瀏覽器會將接收到的token值存儲在Local Storage中,(通過js代碼寫入Local Storage,通過js獲取,並不會像cookie一樣自動攜帶)

③再次訪問時服務器端對token值的處理:服務器對瀏覽器傳來的token值進行解密,解密完成后進行用戶數據的查詢,如果查詢成功,則通過認證,實現狀態保持,所以,即時有了多台服務器,服務器也只是做了token的解密和用戶數據的查詢,它不需要在服務端去保留用戶的認證信息或者會話信息,這就意味着基於token認證機制的應用不需要去考慮用戶在哪一台服務器登錄了,這就為應用的擴展提供了便利,解決了session擴展性的弊端。

四、用戶身份驗證:Token與Session

開放接口Api服務其實就是客戶端與服務端無狀態交互的一種形式,這有點類似REST(Representational State Transfer)風格。
普通網站應用一般使用session進行登錄用戶信息的存儲和驗證(有狀態),而開放接口服務/REST資源請求則使用Token進行登錄用戶信息的驗證(無狀態)。Token更像是一個精簡版的session。Session主要用於保持會話信息,會在客戶端保存一份cookie來保持用戶會話有效性,而Token則只用於登錄用戶的身份鑒權。所以在移動端使用Token會比使用Session更加簡易並且有更高的安全性,同時也更加符合RESTful中無狀態的定義。

五、Token生成原理
服務端生成的Token一般為隨機的非重復字符串,根據應用對安全性的不同要求,會將其添加時間戳(通過時間判斷Token是否被盜用)或url簽名(通過請求地址判斷Token是否被盜用)后加密進行傳輸。一般Token內容包含有:用戶名/appid,密碼/appsecret, 授權url,用戶自定義token(用戶自定義簽名),時間戳,有效期時長(秒), 系統簽名(sign)等。

六、Api接口服務調用流程:
1. 首先要獲取全局唯一的接口調用憑據(access_token)。該過程務必使用https安全傳輸協議,否則被攔截監聽了,用戶名和密碼等重要數據就都泄漏了。
具體過程:
a. 客戶端向服務端通過https協議發送請求,參數包含用戶名、密碼、請求類型等
b. 服務端接到請求后,驗證用戶信息是否正確,如果正確,返回access_token和expires。否則返回errorcode和errmsg。
c. 服務端access_token可以存儲在session或者redis等內存數據庫中,鍵名(key)為user_id,鍵值為access_token。
d. 客戶端獲得access_token后,保存到file或redis等內存數據庫中。不推薦保存到session或數據庫中,保存到session數據容易丟失,保存到數據庫因為涉及IO讀寫,性能較低。
2. 通過RESTful風格的資源請求格式調用接口,如:
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
正常情況下,服務端會返回JSON數據包給調用者,成功則返回包含業務數據內容的JSON數據包,失敗則返回包含errcode和errmsg的JSON數據包

七、對於敏感的api接口,需使用https協議
http叫超文本傳輸協議,使用TCP端口80,默認情況下數據是明文傳送的,數據可以通過抓包工具捕獲到,因此在interner上,有些比較重要的站點的http服務器需要使用PKI(公鑰基礎結構)技術來對數據加密!這也就是https了; 
https叫安全的超文本傳輸協議,使用TCP端口443,他的數據會用PKI中的公鑰進行加密,這樣抓包工具捕獲到的數據包也沒有辦法看包中的內容,因為他沒有密鑰,當然篡改也就沒有什么意義了,安全性大大提高,要解密數據的話就要用到PKI中的私鑰。所以一些安全性比較高的網站如:網上銀行,電子商務網站都需要用https訪問!

八、微信access_token設計的原理解析
1. appid:接口身份證號。
2. appsecret:密碼。
3. access_token:公眾號的全局唯一接口調用憑據,,公眾號調用各接口時都需使用access_token。access_token是加密的字符串,其目的是為了接口安全考慮,不然隨便就能調用微信服務器的接口會有很大風險。access_token包含的信息有appid, secret, 用戶自定義token,授權url,有效時長等。(登陸后的憑據,證明你已經登陸,相當於你拿着票去看演唱會,說明你已經買票了,才會讓你進)。
4. expires_in:access_token過期時間,因為這里是第三方服務器調用,所以微信服務器必須返回告知給第三方服務器過期時間,從而讓第三方服務器更好處理。access_token的有效期目前為2個小時,需定時刷新,重復獲取將導致上次獲取的access_token失效。
5. openid:為了識別用戶,每個用戶針對每個公眾號會產生一個安全的OpenID,OpenID是使用用戶微信號加密后的結果,每個用戶對每個公眾號有一個唯一的OpenID,開發者可通過OpenID來獲取用戶基本信息。
6. unionid:用來區分用戶的唯一性,因為只要是同一個微信開放平台帳號下的移動應用、網站應用和公眾帳號,用戶的UnionID是唯一的。換句話說,同一用戶,對同一個微信開放平台帳號下的不同應用,UnionID是相同的。

接口調用請求說明
https請求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
返回說明
正常情況下,微信會返回下述JSON數據包給公眾號:
{"access_token":"ACCESS_TOKEN","expires_in":7200} (access_token的存儲至少要保留512個字符空間,expires_in單位是秒,有效期目前為2個小時,即7200秒)
錯誤時微信會返回錯誤碼等信息,JSON數據包示例如下(該示例為AppID無效錯誤):
{"errcode":40013,"errmsg":"invalid appid"}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM