1. 程式人生 > 其它 >Restful安全認證及許可權的解決方案

Restful安全認證及許可權的解決方案

一、Restful安全認證常用方式  1.Session+Cookie  傳統的Web認證方式。需要解決會話共享及跨域請求的問題。  2.JWT  JSON Web Token。  3.OAuth  支援兩方和三方認證,是目前使用比較廣泛的安全認證方式,但對於不使用第三方登入的認證的方式不太適用。  二、JWT簡介  JWT由三部分組成,包括Header、Payload和Signature。 

JSON Web Token example:  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.  eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0. yRQYnWzskCZUxPwaQupWkiUzKELZ49eM7oWxAQK_ZXw 

Example Header: 

{ 
  “alg”: “HS256”, 
  “typ”: “JWT” 
} 

通過加密後得到:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9  一般Payload包括以下幾方面內容:   iss: The issuer of the token   sub: The subject of the token   aud: The audience of the token   exp: Token expiration time defined in Unix time   nbf: “Not before” time that identifies the time before which the JWT must not be accepted for processing   iat: “Issued at” time, in Unix time, at which the token was issued   jti: JWT ID claim provides a unique identifier for the JWT  Example Payload: 

{ 
  “iss”: “toptal.com”, 
  “exp”: 1426420800, 
  “https://www.toptal.com/jwt_claims/is_admin”: true, 
  “company”: “Toptal”, 
  “awesome”: true 
} 

通過加密後得到:  eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0 Example Signature:  通過金鑰對Header和Payload生成簽名。  JWT的優勢:  無狀態,可以無限水平擴充套件  可重用,可以在多語言多平臺多域中使用  安全性高,由於沒有使用Cookie,因此可以防止跨站請求偽造(CSRF)攻擊  效能好,只驗證令牌並解析其內容  三、JWT認證方式的實現方式  1.客戶端不需要持有金鑰,由服務端通過金鑰生成Token。  2.客戶端登入時通過賬號和密碼到服務端進行認證,認證通過後,服務端通過持有的金鑰生成Token,Token中一般包含失效時長和使用者唯一標識,如使用者ID,服務端返回Token給客戶端。  3.客戶端儲存服務端返回的Token。  4.客戶端進行業務請求時在Head的Authorization欄位裡面放置Token,如:  Authorization: Bearer Token  5.服務端對請求的Token進行校驗,並通過Redis查詢Token是否存在,主要是為了解決使用者登出,但Token還在時效內的問題,如果Token在Redis中存在,則說明使用者已登出;如果Token不存在,則校驗通過。  6.服務端可以通過從Token取得的使用者唯一標識進行相關許可權的校驗,並把此使用者標識賦予到請求引數中,業務可通過此使用者標識進行業務處理。  7.使用者登出時,服務端需要把還在時效內的Token儲存到Redis中,並設定正確的失效時長。 

四、在實際環境中如何使用JWT  1.Web應用程式  在令牌過期前重新整理令牌。如設定令牌的過期時間為一個星期,每次使用者開啟Web應用程式,服務端每隔一小時生成一個新令牌。如果使用者一個多星期沒有開啟應用,他們將不得不再次登入。  2.移動應用程式  大多數移動應用程式使用者只進行一次登入,定期重新整理令牌可以使使用者長期不用登入。  但如果使用者的手機丟失,則可提供一種方式由使用者決定撤銷哪個裝置的令牌。當然,這就需要服務端記錄裝置的名稱,例如“maryo的iPad”。然後使用者可以去申請並撤銷獲得“maryo的iPad”。當用戶修改密碼時需要服務端把原Token儲存到Redis上,使其失效。  為了防止Token被竊取,最好把JWT和HTTPS結合起來使用。  五、如何實現安全認證與許可權的結合  服務端生成的Token中需要包含使用者唯一標識,這樣使用者進行業務請求時,服務端通過附帶的Token獲取使用者唯一標識,通過此標識進行許可權檢查。  六、更換Token  為了解決高併發訪問時更換Token, 有可能造成用舊的Token的訪問失敗。 在快取中不儲存Token,而是儲存一個計數,每次更換Token時,計數加1,這個計數的值會跟使用者ID一起加密後儲存在新生成的Token中,返回給使用者,使用者每次訪問時攜帶這個Token。驗證使用者Token時,用Token中的計數與快取中儲存的計數比較,如果差值範圍在1~2之間就認為Token有效,這樣即使在併發訪問時,更換Token,計數值雖然不等,但在規定的差值範圍內,也被認為有效,這樣就解決了上面的Token失效問題。  七、附錄  https://www.toptal.com/web/cookie-free-authentication-with-json-web-tokens-an-example-in-laravel-and-angularjs  http://stackoverflow.com/questions/26739167/jwt-json-web-token-automatic-prolongation-of-expiration  http://www.haomou.net/2014/08/13/2014_web_token/  https://jwt.io/