隨著前端登錄場(chǎng)景的日益復(fù)雜化和技術(shù)思想的不斷演進(jìn),前端在登錄方面的知識(shí)結(jié)構(gòu)變得越來(lái)越復(fù)雜。對(duì)于前端開發(fā)者來(lái)說(shuō),在日常工作中根據(jù)不同的登錄場(chǎng)景提供合適的解決方案是我們的職責(zé)所在,本文將梳理前端登錄的演變過(guò)程,希望能幫助跟我遇到同樣問(wèn)題的開發(fā)者。
無(wú)狀態(tài)的HTTP
HTTP是無(wú)狀態(tài)的,每條請(qǐng)求都是獨(dú)立進(jìn)行的。同一個(gè)用戶多次發(fā)起請(qǐng)求,服務(wù)端無(wú)法識(shí)別多個(gè)HTTP請(qǐng)求來(lái)自同一個(gè)用戶。為了解決這個(gè)問(wèn)題,引入了會(huì)話機(jī)制(session)。
基于會(huì)話(session)的認(rèn)證
會(huì)話(session)機(jī)制,使每條HTTP請(qǐng)求之間保持客戶端的狀態(tài)信息。session對(duì)象保存在服務(wù)端的內(nèi)存或數(shù)據(jù)庫(kù)中,這個(gè)session對(duì)象包含有用戶的基本信息。sessionId(會(huì)話ID)保存在客戶端中的cookie或localstorage中,每次客戶端向服務(wù)端發(fā)送請(qǐng)求時(shí),都會(huì)攜帶sessionId,服務(wù)端拿到sessionId對(duì)該請(qǐng)求進(jìn)行身份驗(yàn)證。sessionId在請(qǐng)求傳輸過(guò)程中,可以被放置在cookie中,也可以放置在body中。
基于會(huì)話的認(rèn)證方式是傳統(tǒng)的方法,在很長(zhǎng)的時(shí)間內(nèi)被使用。但也存在一些缺點(diǎn):
- 服務(wù)器負(fù)擔(dān)大。服務(wù)端需要為每個(gè)用戶維護(hù)一個(gè)會(huì)話對(duì)象,這可能在大規(guī)模應(yīng)用中導(dǎo)致服務(wù)器負(fù)載增加
- 水平擴(kuò)展困難。在分布式架構(gòu)中,即應(yīng)用程序在多個(gè)服務(wù)器上運(yùn)行時(shí),用戶可能會(huì)在不同的服務(wù)器上交替訪問(wèn)應(yīng)用程序,所以需要確保服務(wù)器之間可以共享會(huì)話狀態(tài)。
- 不適用于無(wú)狀態(tài)服務(wù)。對(duì)于RESTful API這種無(wú)狀態(tài)服務(wù),更適合基于令牌的認(rèn)證方式。
跨域認(rèn)證
隨著前后端開發(fā)模式的變化,前端和后端更傾向于分開部署,前端的靜態(tài)資源部署在一個(gè)服務(wù)器中,后端的API部署在另外一個(gè)服務(wù)器中。這意味著前端的登錄需要進(jìn)行跨域認(rèn)證??缬蛘J(rèn)證即使用跨域請(qǐng)求的方式,進(jìn)行身份認(rèn)證。常見的幾種跨域認(rèn)證方案:
- JSOP:只能用于跨域請(qǐng)求,不能進(jìn)行身份驗(yàn)證
- CORS:可以進(jìn)行跨域請(qǐng)求和身份認(rèn)證。但是當(dāng)多個(gè)業(yè)務(wù)系統(tǒng)調(diào)用同一個(gè)API服務(wù)下的接口時(shí),隨著業(yè)務(wù)系統(tǒng)數(shù)量的增長(zhǎng),后端開發(fā)人員需要頻繁地更改跨域配置才能使新開發(fā)的系統(tǒng)可以進(jìn)行跨域請(qǐng)求。當(dāng)出現(xiàn)這種情況時(shí),使用nginx反向代理將跨域的控制權(quán)移交至前端,是更好的方案。
- 代理:使用nginx做代理,將跨域請(qǐng)求轉(zhuǎn)發(fā)至目標(biāo)服務(wù)器,并將響應(yīng)返回給客戶端。
iframe場(chǎng)景下,使用localstorage做跨域存儲(chǔ),通過(guò)postmessage和iframe的方式跨域共享localstorage,但是safari不能使用postMessage,可以改用url方式跨域共享localstorage
基于令牌(token)的認(rèn)證
為了解決在分布式架構(gòu)中session認(rèn)證存在的問(wèn)題,可以使用基于token的認(rèn)證方式。由于token只會(huì)存儲(chǔ)在客戶端,這樣可以減少服務(wù)端的負(fù)擔(dān)和提升了服務(wù)端水平擴(kuò)展能力。
基于令牌(token)的認(rèn)證時(shí)序圖
下面是基于令牌認(rèn)證的時(shí)序圖:
優(yōu)點(diǎn):
- 減少服務(wù)端的負(fù)擔(dān)。因?yàn)閠oken只會(huì)存儲(chǔ)在客戶端上,不會(huì)存儲(chǔ)在服務(wù)端。
- 提升了服務(wù)端水平擴(kuò)展能力。因?yàn)榉?wù)端水平擴(kuò)展不再需要處理會(huì)話狀態(tài)的同步邏輯。
缺點(diǎn):
- 簽發(fā)的token無(wú)法撤銷。token包含了有效期信息,在整個(gè)有效期內(nèi)不能撤銷,直至過(guò)期。
- 無(wú)法實(shí)現(xiàn)單點(diǎn)登出。如果使用令牌方式實(shí)現(xiàn)單點(diǎn)登錄SSO功能,那么難以實(shí)現(xiàn)單點(diǎn)登出SLO。因?yàn)閱吸c(diǎn)登出涉及到在所有相關(guān)聯(lián)系統(tǒng)中注銷用戶,所以要實(shí)現(xiàn)此功能需要額外的機(jī)制配合。
以上是最基礎(chǔ)版本的令牌的認(rèn)證方式,還存在著一些缺點(diǎn),主要用來(lái)闡述令牌認(rèn)證的核心流程。要規(guī)避掉上述缺點(diǎn),還需要配合其他機(jī)制(下面OAUTH部分會(huì)更深一步講解)。
令牌(token)的生成
token最常見的方式是JWT(JSON Web Token),JWT是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)((RFC 7519),該token被設(shè)計(jì)為緊湊且安全的,特別適用于分布式站點(diǎn)的單點(diǎn)登錄(SSO)場(chǎng)景。JWT由三部分組成,由.
分割,形如:Header.Payload.Signature
。
1. Header(頭部)
Header部分是一個(gè)JSON對(duì)象,描述JWT元數(shù)據(jù),如下:
{
"alg": "HS256",
"typ": "JWT"
}
alg
表示簽名的算法,type
表示令牌的類型。最后將上面的JSON對(duì)象使用Base64URL算法轉(zhuǎn)成字符串。
2. Payload(負(fù)載)
payload部分是一個(gè)JSON對(duì)象,表示JWT實(shí)際傳輸?shù)臄?shù)據(jù),官方定義了如下字段供選擇:
- iss (issuer):簽發(fā)人
- exp (expiration time):過(guò)期時(shí)間
- sub (subject):主題
- aud (audience):受眾
- nbf (Not Before):生效時(shí)間
- iat (Issued At):簽發(fā)時(shí)間
- jti (JWT ID):編號(hào)
也可以自定義字段,最后將上面的JSON對(duì)象使用Base64URL算法轉(zhuǎn)成字符串。
3. Signature(簽名)
signature部分是對(duì)前兩部分的簽名,防止數(shù)據(jù)被篡改。公式如下:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
secret
是由服務(wù)端才有的密鑰。
單點(diǎn)登錄(SSO)
用戶只需要登錄一次,就可以在多個(gè)相關(guān)聯(lián)的系統(tǒng)上訪問(wèn),避免了多次登錄的麻煩。單點(diǎn)登錄簡(jiǎn)化了登錄流程,提升了用戶體驗(yàn)。目前有兩種比較常見的實(shí)現(xiàn)方式:CAS
和OIDC
。
CAS
CAS(Central Authentication Service)是一種用于實(shí)現(xiàn)單點(diǎn)登錄SSO的開源協(xié)議。它提供了一個(gè)中心化的認(rèn)證服務(wù)器(CAS),CAS服務(wù)器負(fù)責(zé)用戶的登錄和身份認(rèn)證,并生成一個(gè)票據(jù)(ticket)用于訪問(wèn)其他應(yīng)用程序。如下圖是CAS標(biāo)準(zhǔn)流程的時(shí)序圖:
需要注意的幾點(diǎn):
- CAS是基于票據(jù)(ticket)實(shí)現(xiàn)單點(diǎn)登錄的。票據(jù)是一種身份驗(yàn)證憑據(jù),與token有一定區(qū)別。
- CAS中包含有TGT和ST兩種ticket。TGT是長(zhǎng)期有效的憑據(jù),用于獲取短期的ST憑據(jù);ST憑據(jù)用來(lái)向特定服務(wù)驗(yàn)證身份的。
OIDC(OpenID Connect)
OAUTH是一個(gè)授權(quán)協(xié)議,在全世界得到了廣泛的應(yīng)用,目前是2.0版本,但并不是專門針對(duì)單點(diǎn)登錄SSO設(shè)計(jì)的協(xié)議。OIDC是基于OAUTH實(shí)現(xiàn)的身份認(rèn)證協(xié)議,是OAUTH的超集,可以實(shí)現(xiàn)單點(diǎn)登錄功能。與CAS不同的是,OIDC是基于token的認(rèn)證方式。
1. OAUTH2.0
OAUTH是一個(gè)授權(quán)協(xié)議,是為了解決同一個(gè)賬號(hào)可以登錄所有應(yīng)用的問(wèn)題?,F(xiàn)在很多第三方應(yīng)用都接入了微信登錄,那么微信登錄就是一個(gè)大的身份認(rèn)證服務(wù),所有接入了微信登錄體系的APP,都可以使用微信賬號(hào)直接登錄。
1.1. OAUTH2.0 原理
OAuth 2.0的運(yùn)行流程如下圖,摘自RFC 6749。
認(rèn)證服務(wù)器除了返回access token,refresh token也是可選項(xiàng)。
- access token:表示訪問(wèn)令牌。有效期短,解決token無(wú)法撤銷問(wèn)題。
- refresh token:表示更新令牌。有效期長(zhǎng),用于獲取access token。
2. OIDC
下圖是網(wǎng)上找到的一張基于token實(shí)現(xiàn)單點(diǎn)登錄的時(shí)序圖,雖然與標(biāo)準(zhǔn)的OIDC流程不一樣,但是也大致說(shuō)清楚了基于token實(shí)現(xiàn)單點(diǎn)登錄的流程
CAS與OIDC的總結(jié):文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-800998.html
- CAS業(yè)務(wù)系統(tǒng)是基于session的保持登錄態(tài),而OIDC業(yè)務(wù)系統(tǒng)是基于token的
- CAS單點(diǎn)登錄的方式更適合企業(yè)內(nèi)部各個(gè)業(yè)務(wù)系統(tǒng)之間統(tǒng)一單點(diǎn)登錄;而OIDC除了單點(diǎn)登錄,還可以為第三方軟件提供授權(quán)服務(wù)
作者:復(fù)讀機(jī)
鏈接:https://juejin.cn/post/7324351711656394779
來(lái)源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-800998.html
到了這里,關(guān)于從普通登錄到單點(diǎn)登錄(SSO)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!