1. 程式人生 > >Restful安全認證及權限的解決方案

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

解決 三方登錄 cati rest oiv 保存 無限 some 一次

一、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/

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