HTTP常見的幾種認證機制


幾種常用的認證機制

===================轉自https://www.cnblogs.com/xiekeli/紅心李的文章======================

我是一個測試人員,在學習postman進行鑒權發現的好文,特轉載!

HTTP Basic Auth

HTTP Basic Auth簡單點說明就是每次請求API時都提供用戶的username和password,簡言之,Basic Auth是配合RESTful API 使用的最簡單的認證方式,只需提供用戶名密碼即可,但由於有把用戶名密碼暴露給第三方客戶端的風險,在生產環境下被使用的越來越少。因此,在開發對外開放的RESTful API時,盡量避免采用HTTP Basic Auth

OAuth

OAuth(開放授權)是一個開放的授權標准,允許用戶讓第三方應用訪問該用戶在某一web服務上存儲的私密的資源(如照片,視頻,聯系人列表),而無需將用戶名和密碼提供給第三方應用。

OAuth允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的第三方系統(例如,視頻編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth讓用戶可以授權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非所有內容
下面是OAuth2.0的流程:

這種基於OAuth的認證機制適用於個人消費者類的互聯網產品,如社交類APP等應用,但是不太適合擁有自有認證權限管理的企業應用;

Cookie認證機制就是為一次請求認證在服務端創建一個Session對象,同時在客戶端的瀏覽器端創建了一個Cookie對象;通過客戶端帶上來Cookie對象來與服務器端的session對象匹配來實現狀態管理的。默認的,當我們關閉瀏覽器的時候,cookie會被刪除。但可以通過修改cookie 的expire time使cookie在一定時間內有效;

Token Auth

Token Auth的優點

Token機制相對於Cookie機制又有什么好處呢?

  • 支持跨域訪問: Cookie是不允許垮域訪問的,這一點對Token機制是不存在的,前提是傳輸的用戶認證信息通過HTTP頭傳輸.
  • 無狀態(也稱:服務端可擴展行):Token機制在服務端不需要存儲session信息,因為Token 自身包含了所有登錄用戶的信息,只需要在客戶端的cookie或本地介質存儲狀態信息.
  • 更適用CDN: 可以通過內容分發網絡請求你服務端的所有資料(如:javascript,HTML,圖片等),而你的服務端只要提供API即可.
  • 去耦: 不需要綁定到一個特定的身份驗證方案。Token可以在任何地方生成,只要在你的API被調用的時候,你可以進行Token生成調用即可.
  • 更適用於移動應用: 當你的客戶端是一個原生平台(iOS, Android,Windows 8等)時,Cookie是不被支持的(你需要通過Cookie容器進行處理),這時采用Token認證機制就會簡單得多。
  • CSRF:因為不再依賴於Cookie,所以你就不需要考慮對CSRF(跨站請求偽造)的防范。
  • 性能: 一次網絡往返時間(通過數據庫查詢session信息)總比做一次HMACSHA256計算 的Token驗證和解析要費時得多.
  • 不需要為登錄頁面做特殊處理: 如果你使用Protractor 做功能測試的時候,不再需要為登錄頁面做特殊處理.
  • 基於標准化:你的API可以采用標准化的 JSON Web Token (JWT). 這個標准已經存在多個后端庫(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft).

基於JWT的Token認證機制實現

JSON Web Token(JWT)是一個非常輕巧的規范。這個規范允許我們使用JWT在用戶和服務器之間傳遞安全可靠的信息。其

JWT的組成

一個JWT實際上就是一個字符串,它由三部分組成,頭部、載荷與簽名。
載荷(Payload)

{ "iss": "Online JWT Builder", "iat": 1416797419, "exp": 1448333419, "aud": "www.example.com", "sub": "jrocket@example.com", "GivenName": "Johnny", "Surname": "Rocket", "Email": "jrocket@example.com", "Role": [ "Manager", "Project Administrator" ] }
  • iss: 該JWT的簽發者,是否使用是可選的;
  • sub: 該JWT所面向的用戶,是否使用是可選的;
  • aud: 接收該JWT的一方,是否使用是可選的;
  • exp(expires): 什么時候過期,這里是一個Unix時間戳,是否使用是可選的;
  • iat(issued at): 在什么時候簽發的(UNIX時間),是否使用是可選的;
    其他還有:
  • nbf (Not Before):如果當前時間在nbf里的時間之前,則Token不被接受;一般都會留一些余地,比如幾分鍾;,是否使用是可選的;

將上面的JSON對象進行[base64編碼]可以得到下面的字符串。這個字符串我們將它稱作JWT的Payload(載荷)。

eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

小知識:Base64是一種基於64個可打印字符來表示二進制數據的表示方法。由於2的6次方等於64,所以每6個比特為一個單元,對應某個可打印字符。三個字節有24個比特,對應於4個Base64單元,即3個字節需要用4個可打印字符來表示。JDK 中提供了非常方便的 BASE64Encoder 和 BASE64Decoder,用它們可以非常方便的完成基於 BASE64 的編碼和解碼

頭部(Header)
JWT還需要一個頭部,頭部用於描述關於該JWT的最基本的信息,例如其類型以及簽名所用的算法等。這也可以被表示成一個JSON對象。

{
"typ": "JWT", "alg": "HS256" }

在頭部指明了簽名算法是HS256算法。
當然頭部也要進行BASE64編碼,編碼后的字符串如下:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

簽名(Signature)
將上面的兩個編碼后的字符串都用句號.連接在一起(頭部在前),就形成了:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0

最后,我們將上面拼接完的字符串用HS256算法進行加密。在加密的時候,我們還需要提供一個密鑰(secret)。如果我們用mystar作為密鑰的話,那么就可以得到我們加密后的內容:

rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

最后將這一部分簽名也拼接在被簽名的字符串后面,我們就得到了完整的JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

在我們的請求URL中會帶上這串JWT字符串:

https://your.awesome-app.com/make-friend/?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

認證過程

下面我們從一個實例來看如何運用JWT機制實現認證:

登錄

  • 第一次認證:第一次登錄,用戶從瀏覽器輸入用戶名/密碼,提交后到服務器的登錄處理的Action層(Login Action);
  • Login Action調用認證服務進行用戶名密碼認證,如果認證通過,Login Action層調用用戶信息服務獲取用戶信息(包括完整的用戶信息及對應權限信息);
  • 返回用戶信息后,Login Action從配置文件中獲取Token簽名生成的秘鑰信息,進行Token的生成;
  • 生成Token的過程中可以調用第三方的JWT Lib生成簽名后的JWT數據;
  • 完成JWT數據簽名后,將其設置到COOKIE對象中,並重定向到首頁,完成登錄過程;

請求認證

基於Token的認證機制會在每一次請求中都帶上完成簽名的Token信息,這個Token信息可能在COOKIE
中,也可能在HTTP的Authorization頭中;

  • 客戶端(APP客戶端或瀏覽器)通過GET或POST請求訪問資源(頁面或調用API);
  • 認證服務作為一個Middleware HOOK 對請求進行攔截,首先在cookie中查找Token信息,如果沒有找到,則在HTTP Authorization Head中查找;
  • 如果找到Token信息,則根據配置文件中的簽名加密秘鑰,調用JWT Lib對Token信息進行解密和解碼;
  • 完成解碼並驗證簽名通過后,對Token中的exp、nbf、aud等信息進行驗證;
  • 全部通過后,根據獲取的用戶的角色權限信息,進行對請求的資源的權限邏輯判斷;
  • 如果權限邏輯判斷通過則通過Response對象返回;否則則返回HTTP 401;

對Token認證的五點認識

對Token認證機制有5點直接注意的地方:

  • 一個Token就是一些信息的集合;
  • 在Token中包含足夠多的信息,以便在后續請求中減少查詢數據庫的幾率;
  • 服務端需要對cookie和HTTP Authrorization Header進行Token信息的檢查;
  • 基於上一點,你可以用一套token認證代碼來面對瀏覽器類客戶端和非瀏覽器類客戶端;
  • 因為token是被簽名的,所以我們可以認為一個可以解碼認證通過的token是由我們系統發放的,其中帶的信息是合法有效的;

 

 


免責聲明!

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



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