HTTP常見的幾種認證機制

幾種經常使用的認證機制

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

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

HTTP Basic Auth

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

OAuth

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

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

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

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

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是由咱們系統發放的,其中帶的信息是合法有效的;
相關文章
相關標籤/搜索