網(wǎng)絡身份的驗證的場景非常普遍,比如用戶登陸后才有權限訪問某些頁面或接口拜鹤。而HTTP通信是無狀態(tài)的框冀,無法記錄用戶的登陸狀態(tài),那么敏簿,如何做身份驗證呢明也?
下面,會從淺入深惯裕,陸續(xù)介紹幾種常用的認證方式和相關概念温数。文章較長,請耐心閱讀蜻势。
1. 鑒權與授權
- 鑒權 Authentication撑刺,指對于一個聲明者所聲明的身份權利,對其所聲明的真實性進行鑒別確認的過程握玛。
例子:用戶名張三够傍,密碼******次员,用戶名和密碼通過挖財驗證,登陸成功 - 授權 Authorization王带,一般是指獲取用戶的委派權限淑蔚。
例子:我是張三,有權訪問git/client/jizhang愕撰,因為gitlab給我進行了授權
一般流程為先鑒權再授權刹衫。而身份驗證指的就是鑒權這個步驟。
1.2 常用的鑒權方式
-
方式一:HTTP Basic Authentication (401)
客戶端發(fā)送http request 給服務器,服務器驗證該用戶是否已經(jīng)登錄驗證過了搞挣,如果沒有的話带迟,服務器會返回一個401 Unauthozied
給客戶端,并且在Response 的 header “WWW-Authenticate” 中添加信息囱桨。
然后仓犬,瀏覽器彈出輸入框要求輸入用戶名和密碼。
image
用戶輸入正確的用戶名和密碼后舍肠,瀏覽器用BASE64編碼搀继,放在Authorization header中發(fā)送給服務器。如下圖:
image
最后翠语,服務器將Authorization header中的用戶名密碼取出叽躯,進行驗證, 如果驗證通過肌括,將根據(jù)請求点骑,發(fā)送資源給客戶端。 方式二:Session-cookie
方式三:Token
方式四:OAuth(開發(fā)授權)
后三種驗證方式下面逐漸展開講解谍夭。
2. Token VS Cookies
2.1 Cookies
Cookies是傳統(tǒng)的鑒權方式黑滴,通過瀏覽器攜帶的Cookies字段來進行狀態(tài)存儲。特點如下:
- 認證信息在服務端需要存儲紧索。cookies攜帶sessionId袁辈,用戶經(jīng)過認證之后,應用都要在服務端做一次記錄齐板,以方便用戶下次請求的鑒別吵瞻。session的保存方法多種多樣,可以保存在文件中甘磨,也可以內存里橡羞,或第三方媒介,比如redis或者mongodb济舆。隨著認證用戶的增多卿泽,服務端的開銷會明顯增大。
缺點
- 一般不需要客戶端存儲。服務端通過reponse:
Set-Cookie
頭信息為客戶端設置cookie签夭,客戶端不需要做特殊配置齐邦,瀏覽器會在后續(xù)的ajax請求中自動帶上cookie。
image - 有CSRF(跨站點偽造請求)風險第租。
缺點
- 移動端用在使用cookie時有各種不便利和局限措拇。
缺點
- Cookie可以在同一域名下或者同一主域不同子域下共享,一旦跨主域慎宾,就無法共享
缺點
- 分布式應用上丐吓,可能會限制負載均衡器的能力。用戶認證之后趟据,服務端做認證記錄券犁,如果認證的記錄被保存在內存中的話,這意味著用戶下次請求還必須要請求在這臺服務器上,這樣才能拿到授權的資源汹碱,這樣在分布式的應用上粘衬,相應的限制了負載均衡器的能力。這也意味著限制了應用的擴展能力咳促。
缺點
2.2 Token
Token是服務端生成的一串字符串稚新,以作客戶端進行請求的一個令牌,當?shù)谝淮蔚卿浐蟮茸海掌魃梢粋€Token便將此Token返回給客戶端枷莉,以后客戶端只需帶上這個Token前來請求數(shù)據(jù)即可,無需再次帶上用戶名和密碼尺迂。
最簡單的token組成:uid(用戶唯一的身份標識)、time(當前時間的時間戳)冒掌、sign(簽名噪裕,由token的前幾位+鹽以哈希算法壓縮成一定長的十六進制字符串,可以防止惡意第三方拼接token請求服務器)股毫。
相比Cookies膳音,Token的優(yōu)勢明顯多了蛹疯。
- 服務端無需存儲認證信息承绸。因為Token本身就存儲了認證信息耻蛇。
- 需要前端存儲(建議用
localstorage
)芋忿』派辏客戶端通過request:Authorization
頭信息設置Token泊柬,發(fā)給服務端做驗證汤功。缺點
image - 無CSRF風險
- 適合移動端身份認證
- token支持各類跨域
Javascript支持Token如下:
// JS
var res = new XMLHttpRequest();
...
req.setRequestHeader('Authorization',accesstoken);
// JQuery
$.ajax({
url: api,
type: "GET",
headers: { "Authorization": "Bearer " + token}
})
2.3 什么是JWT(Json web token)
JWT是實現(xiàn)Web應用會話管理的一種方式姜骡。廣義上來講宣肚,它是一種開發(fā)標準想罕,而非技術實現(xiàn)(大部分的語言平臺都有按照它規(guī)定的內容提供了自己的技術實現(xiàn));狹義上講霉涨,它就是用來傳遞的Token字符串按价。
看一下JWT是如何傳遞的惭适。
它長得像下面這樣。楼镐。癞志。
JWT是如何對信息簽名加密的呢?
要前面的信息分為三部分:header框产,payload和signature凄杯。
- header:說明這個JWT簽發(fā)的時候所使用的簽名和摘要算法
{
"typ": "JWT",
"alg": "HS256"
}
- payload:用來承載要傳遞的數(shù)據(jù)
{
"sub": "1234567890",
"name": "john Doe",
"admin": true
}
- signature:密鑰
簽名過程:把header
和payload
對應的json結構進行base64url編碼之后得到的兩個串用英文句點號拼接起來,然后根據(jù)header里面alg指定的簽名算法生成出來的茅信。函數(shù)如下:
HMACSH256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
HMAC計算:https://1024tools.com/hmac
下面的內容都是基于Token認證
3. Token有效期
顯而易見盾舌,身份驗證必須要有有效期!那么蘸鲸,如何在”用戶無感知”的情況下處理Token失效妖谴?
- 方案一: 服務器端保存 Token 狀態(tài),用戶每次操作都會自動刷新(推遲) Token 的過期時間酌摇。
- 缺點:請求次數(shù)多時膝舅,每次都刷新過期時間代價較大
- 方案二:refresh token
- 優(yōu)點:服務端不需要刷新token,避免頻繁讀寫操作
那讓我們看看什么是refresh token窑多?
3.1 Refresh token
第一步仍稀,登陸。
第二步埂息,業(yè)務請求
第三步技潘,Token過期,刷新Token
那么千康,如果refresh token也過期呢享幽?好吧,請重新登陸吧拾弃。
3.2 Refresh token自動續(xù)期
可以在Refresh token每次使用時值桩,更新它的過期時間。也可以在創(chuàng)建Refresh token時豪椿,就指定它的過期時間奔坟,比如,距離創(chuàng)建時間XXX天后過期搭盾。
看到這里咳秉,大家應該覺得身份驗證可以完美收官了。增蹭。滴某。但是,前面所講的技術都有一個大前提,就是霎奢,認證服務和業(yè)務服務在一起的户誓。
比如,上淘寶網(wǎng)幕侠,用淘寶賬號登陸帝美,沒有問題。
但是晤硕,現(xiàn)在很多網(wǎng)站都沒有自己的賬號密碼悼潭,而是通過第三方賬號登陸,比如微信舞箍,微博舰褪,QQ。
這種認證服務和業(yè)務服務分離的情況下疏橄,如何做身份認證呢占拍?繼續(xù)下面兩節(jié)吧!
4. 分離認證服務
認證服務和業(yè)務服務分離時捎迫,利用Token的無狀態(tài)特性晃酒,實現(xiàn)單點登陸。
第一步窄绒,登錄和業(yè)務請求
第二步贝次,更新Token
這樣好像完美多了。但是彰导,又有個問題蛔翅,上圖是在認證服務器信任業(yè)務服務器的場景下工作的。
問題1:如何處理不受信任的業(yè)務服務器呢位谋?
答案:使用非對稱加密簽名搁宾,認證服務器使用密鑰A簽發(fā)(私鑰),業(yè)務服務器使用密鑰B驗證(公鑰)倔幼。
問題2: 多個業(yè)務服務器之間使用相同的Token對用戶來說是不安全的!K损同!任何一個服務器拿到Token都可以仿冒用戶去另一個服務器處理業(yè)務,怎么處理鸟款?
答案:認證服務器產生Token時膏燃,需要把使用方-業(yè)務服務器相關信息記錄在Token中。
問題3:如果用戶不信任業(yè)務服務器呢何什?
答案:讓『認證服務』幫助用戶甄別『業(yè)務服務』组哩!
開發(fā)式API可以解決上面的所有問題。
5. 開放式API - OAuth
OAuth 2.0是一個關于授權(authorization)的開放網(wǎng)絡標準。
認證服務器不公開公鑰伶贰, 業(yè)務服務需要在認證服務注冊蛛砰,通過審核,拿到特定公鑰黍衙。
然后泥畅,用戶通過認證服務器授權,將授權數(shù)據(jù)加密到Token中琅翻。
OAuth有四個角色:
- 資源擁有者(Resource Owner) - 用戶
- 客戶端(Client) - 三方應用
- 資源服務器(Resource Server) - 存放用戶資源和信息
- 授權服務器(Authorization Server) - 給三方頒發(fā)授權令牌(access token)
授權流程如下圖: