一、Restful安全認(rèn)證常用方式
1.Session+Cookie
傳統(tǒng)的Web認(rèn)證方式。需要解決會(huì)話共享及跨域請(qǐng)求的問題。
2.JWT
JSON Web Token。
3.OAuth
支持兩方和三方認(rèn)證,是目前使用比較廣泛的安全認(rèn)證方式,但對(duì)于不使用第三方登錄的認(rèn)證的方式不太適用。
二、JWT簡(jiǎn)介
JWT由三部分組成,包括Header、Payload和Signature。
JSON Web Token example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0.
yRQYnWzskCZUxPwaQupWkiUzKELZ49eM7oWxAQK_ZXw
Example Header:
{
“alg”: “HS256”,
“typ”: “JWT”
}
通過加密后得到:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
一般Payload包括以下幾方面內(nèi)容:
? 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:
通過密鑰對(duì)Header和Payload生成簽名。
JWT的優(yōu)勢(shì):
?無狀態(tài),可以無限水平擴(kuò)展
?可重用,可以在多語言多平臺(tái)多域中使用
?安全性高,由于沒有使用Cookie,因此可以防止跨站請(qǐng)求偽造(CSRF)攻擊
?性能好,只驗(yàn)證令牌并解析其內(nèi)容
三、JWT認(rèn)證方式的實(shí)現(xiàn)方式
1.客戶端不需要持有密鑰,由服務(wù)端通過密鑰生成Token。
2.客戶端登錄時(shí)通過賬號(hào)和密碼到服務(wù)端進(jìn)行認(rèn)證,認(rèn)證通過后,服務(wù)端通過持有的密鑰生成Token,Token中一般包含失效時(shí)長(zhǎng)和用戶唯一標(biāo)識(shí),如用戶ID,服務(wù)端返回Token給客戶端。
3.客戶端保存服務(wù)端返回的Token。
4.客戶端進(jìn)行業(yè)務(wù)請(qǐng)求時(shí)在Head的Authorization字段里面放置Token,如:
Authorization: Bearer Token
5.服務(wù)端對(duì)請(qǐng)求的Token進(jìn)行校驗(yàn),并通過Redis查找Token是否存在,主要是為了解決用戶注銷,但Token還在時(shí)效內(nèi)的問題,如果Token在Redis中存在,則說明用戶已注銷;如果Token不存在,則校驗(yàn)通過。
6.服務(wù)端可以通過從Token取得的用戶唯一標(biāo)識(shí)進(jìn)行相關(guān)權(quán)限的校驗(yàn),并把此用戶標(biāo)識(shí)賦予到請(qǐng)求參數(shù)中,業(yè)務(wù)可通過此用戶標(biāo)識(shí)進(jìn)行業(yè)務(wù)處理。
7.用戶注銷時(shí),服務(wù)端需要把還在時(shí)效內(nèi)的Token保存到Redis中,并設(shè)置正確的失效時(shí)長(zhǎng)。
四、在實(shí)際環(huán)境中如何使用JWT
1.Web應(yīng)用程序
在令牌過期前刷新令牌。如設(shè)置令牌的過期時(shí)間為一個(gè)星期,每次用戶打開Web應(yīng)用程序,服務(wù)端每隔一小時(shí)生成一個(gè)新令牌。如果用戶一個(gè)多星期沒有打開應(yīng)用,他們將不得不再次登錄。
2.移動(dòng)應(yīng)用程序
大多數(shù)移動(dòng)應(yīng)用程序用戶只進(jìn)行一次登錄,定期刷新令牌可以使用戶長(zhǎng)期不用登錄。
但如果用戶的手機(jī)丟失,則可提供一種方式由用戶決定撤銷哪個(gè)設(shè)備的令牌。當(dāng)然,這就需要服務(wù)端記錄設(shè)備的名稱,例如“maryo的iPad”。然后用戶可以去申請(qǐng)并撤銷獲得“maryo的iPad”。當(dāng)用戶修改密碼時(shí)需要服務(wù)端把原Token保存到Redis上,使其失效。
為了防止Token被竊取,最好把JWT和HTTPS結(jié)合起來使用。
五、如何實(shí)現(xiàn)安全認(rèn)證與權(quán)限的結(jié)合
服務(wù)端生成的Token中需要包含用戶唯一標(biāo)識(shí),這樣用戶進(jìn)行業(yè)務(wù)請(qǐng)求時(shí),服務(wù)端通過附帶的Token獲取用戶唯一標(biāo)識(shí),通過此標(biāo)識(shí)進(jìn)行權(quán)限檢查。
六、更換Token
為了解決高并發(fā)訪問時(shí)更換Token, 有可能造成用舊的Token的訪問失敗。 在緩存中不保存Token,而是保存一個(gè)計(jì)數(shù),每次更換Token時(shí),計(jì)數(shù)加1,這個(gè)計(jì)數(shù)的值會(huì)跟用戶ID一起加密后保存在新生成的Token中,返回給用戶,用戶每次訪問時(shí)攜帶這個(gè)Token。驗(yàn)證用戶Token時(shí),用Token中的計(jì)數(shù)與緩存中保存的計(jì)數(shù)比較,如果差值范圍在1~2之間就認(rèn)為Token有效,這樣即使在并發(fā)訪問時(shí),更換Token,計(jì)數(shù)值雖然不等,但在規(guī)定的差值范圍內(nèi),也被認(rèn)為有效,這樣就解決了上面的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/
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。