雲棲號資訊:【點擊查看更多行業資訊】
在這裏您能夠找到不一樣行業的第一手的上雲資訊,還在等什麼,快來!
web
最近幾年,隨着RESTful API開始風靡,使用HTTP header來傳遞認證令牌彷佛變得理所應當,經過 RESTful 的API 接口設計簡化了系統架構, 減小了耦合性, 可讓全部模塊各自獨立的進行改進。redis
不過,在實際的REST API 接口設計過程當中,咱們須要考慮如何讓鑑權變得更安全可靠,例如不會被第三方惡意請求或者保證傳輸過程當中的數據安全以及防止重複提交,本文就一塊兒聊一聊。算法
傳統的Session 認證方式數據庫
首先,咱們說一些傳統的認證方式,衆所周知,HTTP 協議是一種無狀態的協議,而這就意味着若是用戶向咱們的應用提供了用戶名和密碼來進行用戶認證,那麼下一次請求時,用戶還要再一次進行用戶認證才行,由於咱們並不能知道是哪一個用戶發出的請求,因此爲了讓咱們的應用能識別是哪一個用戶發出的請求,咱們只能在服務器存儲一份用戶登陸的信息,這份登陸信息會在響應時傳遞給瀏覽器,告訴其保存爲cookie,以便下次請求時發送給咱們的應用,這樣咱們的應用就能識別請求來自哪一個用戶了,這就是傳統的基於session認證。跨域
而這種方式有不少問題:瀏覽器
首先,佔用資源,這種方式須要每一個用戶通過認證以後,都要在服務端作一次記錄,以方便用戶下次請求的鑑別,一般而言session都是保存在內存中,而隨着認證用戶的增多,服務端的開銷會明顯增大。安全
其次,擴展性差: 客戶端認證以後,服務端作認證記錄,若是認證的記錄被保存在內存中的話,這意味着用戶下次請求還必需要請求在這臺服務器上,這樣才能拿到受權的資源,在一些分佈式的場景下會限制了負載均衡器的能力,會限制了應用的擴展能力。服務器
第三,容易遭受攻擊: 這種基於cookie來進行用戶識別的認證方式, 很容易被截獲,用戶就會很容易受到跨站請求僞造的攻擊。cookie
基於Token 的鑑權方式網絡
因爲session 認證的諸多問題,所以出現了基於token 的鑑權方式,這種方式不須要在服務端去保留用戶的認證信息或者會話信息。這就意味着基於token認證機制的應用不須要去考慮用戶在哪一臺服務器登陸了,這就爲應用的擴展提供了便利。
基於token 鑑權的工做流程以下:
首先,客戶端經過用戶名密碼來請求對應的API接口
第二,服務器會驗證用戶的信息
第三,服務器經過驗證後會發送token給客戶端
第四,客戶端存儲token,並在每次請求時附送上這個token值
第五,服務端驗證token值,並返回數據
這種方式的典型表明就是JWT(Json web token , 它是爲了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519),該token被設計爲緊湊且安全的,特別適用於分佈式站點的單點登陸(SSO)場景。JWT的聲明通常被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也能夠增長一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。
它的特色以下:
體積小(一串字符串)。於是傳輸速度快
傳輸方式多樣。能夠經過 HTTP 頭部(推薦)/URL/POST 參數等方式傳輸
嚴謹的結構化。它自身(在 payload 中)就包含了全部與用戶相關的驗證消息,如用戶可訪問路由、訪問有效期等信息,服務器無需再去鏈接數據庫驗證信息的有效性,而且 payload 支持應用定製
支持跨域驗證,多應用於單點登陸
JWT一般由三部分組成:
頭信息(header)
消息體(payload)
簽名(signature)
以下所示:
// Header { "alg": "HS256", "typ": "JWT" }
// Payload { // reserved claims "iss": "a.com", "exp": "1d", // public claims "http://a.com": true, // private claims "company": "A", "awesome": true }
// $Signature HS256(Base64(Header) + "." + Base64(Payload), secretKey)
// JWT JWT = Base64(Header) + "." + Base64(Payload) + "." + $Signature
其工做流程以下:
首先,客戶端經過發送HTTP 請求把帳號密碼發送給服務短,一般使用的是POST請求, 服務器會校驗帳號與密碼是否合法,若是一致,則根據密鑰生成一個 token 並返回,客戶端收到這個 token 並保存在本地。在這以後,須要訪問一個受保護的路由或資源時,只要附加上 token(一般使用 Header 的 Authorization 屬性)發送到服務器,服務器就會檢查這個 token 是否有效,並作出響應。
服務端接收到 token 以後,會逆向構造過程,解碼出 JWT 的三個部分,這一步能夠獲得 sign 的算法及 payload,結合服務端配置的 secretKey,能夠再次進行 $Signature 的生成獲得新的 $Signature,與原有的 $Signature 比對以驗證 token 是否有效,完成用戶身份的認證,驗證經過纔會使用 payload 的數據。
如何保證接口安全性
要想實現接口的安全性,咱們能夠作到如下幾點:
首先,咱們須要採用HTTPS 對傳輸過程當中的數據進行加密,避免使用HTTP 這種明文傳輸的協議,防止數據直接暴露在公網中,在使用HTTPS的同時要保證時間安全可靠的加密方法和SSL 協議,目前主流的是TLS1.2 和最新的TLS1.3。同時要對證書進行校驗,由於即便是HTTPS協議,證書也是可以被僞造的。
其次,對接口設計通常會加入 token、timestamp和sign 這些參數,不一樣的參數有本身不一樣的用途:
timestamp,即時間戳,它是客戶端調用接口時傳入的當前時間戳,時間戳的目的是用於防止DoS攻擊。每次調用接口時接口都會判斷服務器當前系統時間和接口中傳的的timestamp的差值,若是這個差值超過某個設置的時間,例如設置的時間是3分鐘,那麼這個請求將被攔截掉,若是在設置的超時時間範圍內,是不能阻止DoS攻擊的。timestamp機制只能減輕DoS攻擊的時間,縮短攻擊時間。若是黑客修改了時間戳的值可經過sign簽名機制來處理。
sign,即簽名,一般用於參數簽名,防止參數被非法篡改,最多見的是修改金額等重要敏感參數, sign的值通常是將全部非空參數按照升續排序而後+token+key+timestamp+nonce(隨機數)拼接在一塊兒,而後使用某種加密算法進行加密,這種方式的好處就是,當被劫持後,修改其中的參數值,而後再繼續調用接口,雖然參數的值被修改了,可是由於攻擊者並不清楚sign是如何計算出來的,因此便可是篡改參數的值,但無法修改sign的值,當服務器調用接口前會按照sign的規則從新計算出sign的值而後和接口傳遞的sign參數的值作比較,若是相等表示參數值沒有被篡改,若是不等,表示參數被非法篡改了,則不會返回真實的響應信息。
此外,接口設計時候要實現冪等性操做,所謂的冪等性操做就是爲了防止重複性運算,咱們能夠將生成的簽名和key保存到redis 中,而且設置超時時間,過時自動刪除,當有重複的值存在則不會處理,就能夠防止重複提交,從而保證請求結果一致性。
其使用流程以下:
接口調用方(客戶端)向接口提供方(服務器)申請接口調用帳號,申請成功後,接口提供方會給接口調用方一個AppKey和一個APP Secret參數
調用方申請App Key 和 App Secret 在生成請求時,將參數拼接後進行加密,例如使用HMAC-SHA256 或MD5加密,而後將 App Key, 加密結果追加到請求上。sign=加密(appId + timestamp + key)
服務收到請求後,根據App Key識別出調用方,解密獲得參數以及對時間進行對比,判斷是否超時,而後從字典中查詢到對應的App Secret,與請求參數拼接、加密,與請求中的簽名進行對比,簽名結果相同的爲合法請求。
以上就是給API 接口設計的一些建議,僅供參考,在實際的應用中還能夠
【雲棲號在線課堂】天天都有產品技術專家分享!
課程地址:https://yqh.aliyun.com/live當即加入社羣,與專家面對面,及時瞭解課程最新動態!
【雲棲號在線課堂 社羣】https://c.tb.cn/F3.Z8gvnK
原文發佈時間:2020-07-06
本文做者:阿文
本文來自:「CSDN」,瞭解相關信息能夠關注「CSDN」