<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          關(guān)于鑒權(quán),看懂這篇就夠了

          共 5197字,需瀏覽 11分鐘

           ·

          2021-10-20 15:13


          劉妮萍: 微醫(yī)前端技術(shù)部前端工程師。養(yǎng)魚養(yǎng)花養(yǎng)狗,熬夜蹦迪喝酒。出走半生,歸來仍是三年前端工作經(jīng)驗(yàn)。

          第一篇章

          Cookie 的誕生及其特點(diǎn)

          眾所周知,web 服務(wù)器是無狀態(tài)的,無狀態(tài)的意思就是服務(wù)器不知道用戶上一次請(qǐng)求做了什么,各請(qǐng)求之間是相互獨(dú)立的,客戶信息僅來自于每次請(qǐng)求時(shí)攜帶的,或是服務(wù)器自身保存的且可以被所有請(qǐng)求使用的公共信息。所以為了跟蹤用戶請(qǐng)求的狀態(tài)信息,比如記錄用戶網(wǎng)上購物的購物車歷史記錄,Cookie 應(yīng)運(yùn)而生。
          服務(wù)端在響應(yīng)客戶端請(qǐng)求的時(shí)候,會(huì)向客戶端推送一個(gè) Cookie,這個(gè) Cookie 記錄服務(wù)端上面的一些信息,客戶端在后續(xù)的請(qǐng)求中攜帶這個(gè) Cookie,服務(wù)端可以根據(jù)這個(gè) Cookie 判斷該請(qǐng)求的上下文關(guān)系。

          Cookie 的出現(xiàn),是無狀態(tài)化向狀態(tài)化過渡的一種手段。

          以登錄為例,用戶輸入賬戶名密碼,發(fā)送請(qǐng)求到服務(wù)端,服務(wù)器生成 Cookie 后發(fā)送給瀏覽器,瀏覽器把 Cookie 以 k-v 的形式保存到某個(gè)目錄下的文本文件內(nèi),下一次請(qǐng)求同一網(wǎng)站時(shí)會(huì)把該 Cookie 發(fā)送給服務(wù)器。服務(wù)器校驗(yàn)該接收的 Cookie 與服務(wù)端的 Cookie 是否一致,不一致則驗(yàn)證失敗。這是最初的設(shè)想。0392f2f1b16373a452a7e1656adb1516.webp
          在瀏覽器中存儲(chǔ)的 Cookie 在下圖所示位置
          a231ba844d46a453081e67e6ab3ff3c7.webp
          Cookie的原理決定了他有以下特點(diǎn):
          1,存儲(chǔ)在客戶端,可隨意篡改,不安全
          2,它的內(nèi)容會(huì)隨著 http 交互傳接,影響性能,所以 Cookie 可存儲(chǔ)的數(shù)據(jù)不能過大,最大為 4kb
          3,一個(gè)瀏覽器對(duì)于一個(gè)網(wǎng)站只能存不超過 20 個(gè) Cookie,而瀏覽器一般只允許存放 300 個(gè) Cookie
          4,移動(dòng)端對(duì) Cookie 支持不友好
          5,一般情況下存儲(chǔ)的是純文本,對(duì)象需要序列化之后才可以存儲(chǔ),解析需要反序列化

          二級(jí)域名之間的 Cookie 共享

          還是以登錄 Cookie 為例,比如現(xiàn)在有兩個(gè)二級(jí)域名,http://a.xxx.com(域名 A)和http://b.xxx.com(域名 B)。那么域名 A 的登錄 Cookie 在域名 B 下可以使用嗎?
          默認(rèn)情況下,域名 A 服務(wù)主機(jī)中生成的 Cookie,只有域名 A 的服務(wù)器能拿到,其他域名是拿不到這個(gè) Cookie 的,這就是僅限主機(jī)Cookie

          但是服務(wù)端可以通過顯式地聲明 Cookie 的 domian 來定義它的域,如上例子通過Set-Cookie將域名 A 的登錄 Cookie 的 domain(域)設(shè)置成http://xxx.com(他們共同的頂級(jí)域名),path 設(shè)置成’/’Set-Cookie:name=value;domain=xxx.com;path=’/’,那么域名 B 便可以讀到。
          在新的規(guī)范rfc6265 中,domain 的值會(huì)忽略任何前導(dǎo)點(diǎn),也就是**xxx.com****.xxx.com**都可以在子域中使用。SSO(單點(diǎn)登錄)也是依據(jù)這個(gè)原理實(shí)現(xiàn)的。
          那比如現(xiàn)在又有兩個(gè)域名,a.b.e.f.com.cn (域名 1)和c.d.e.f.com.cn (域名 2),域名 2 想要讀到域名 1 的 Cookie,域名 1 可以聲明哪些 domain 呢?答案是.e.f.com.cn.f.com.cn,瀏覽器不能接受 domian 為.com.cn 的 Cookie,因?yàn)?Cookie 域如果可以設(shè)置成后綴,那可就是峽谷大亂斗了。
          那如果域名 1 設(shè)置Set-Cookie:mykey=myvalue1;domain=e.f.com.cn;path=’/’
          域名 2 設(shè)置Set-Cookie:mykey=myvalue2;domain=e.f.com.cn;path=’/’
          那該域下 mykey 的值會(huì)被覆蓋為 myvalue2,很好理解,同一個(gè)域下,Cookie 的 mykey 是唯一的。通常,我們要通過設(shè)置正確的 domain 和 path,減少不必要的數(shù)據(jù)傳輸,節(jié)省帶寬。

          Cookie-session 模式原理

          隨著交互式 Web 應(yīng)用的興起,Cookie 大小的限制以及瀏覽器對(duì)存儲(chǔ) Cookie 的數(shù)量限制,我們一定需要更強(qiáng)大的空間來儲(chǔ)存大量的用戶信息,比如我們這個(gè)網(wǎng)站是誰登錄了,誰的購物車?yán)锛尤肓松唐返鹊龋?wù)器要保存千萬甚至更多的用戶的信息,Cookie 顯然是不行的。那怎么辦呢?
          試想,我們?cè)诜?wù)器端尋找一個(gè)空間存儲(chǔ)所有用戶會(huì)話的狀態(tài)信息,并給每個(gè)用戶分配不同的“身份標(biāo)識(shí)”,也就是sessionId ,再將這個(gè) sessionId 推送給瀏覽器客戶端存儲(chǔ)在 Cookie 中記錄當(dāng)前的狀態(tài),下次請(qǐng)求的時(shí)候只需要攜帶這個(gè) sessionId,服務(wù)端就可以去那個(gè)空間搜索到該標(biāo)識(shí)對(duì)應(yīng)的用戶。**這樣做既能解決 Cookie 限制問題,又不用暴露用戶信息到客戶端,大大增加了實(shí)用性和安全性。

          那將用戶信息存儲(chǔ)在哪呢?能否直接存在服務(wù)器中?
          如果存在服務(wù)器中,1、這對(duì)服務(wù)器說是一個(gè)巨大的開銷,嚴(yán)重的限制了服務(wù)器的擴(kuò)展能力。2、假設(shè) web 服務(wù)器做了負(fù)載均衡,用戶 user1 通過機(jī)器 A 登入該系統(tǒng),那么下一個(gè)請(qǐng)求如果被轉(zhuǎn)發(fā)到另一臺(tái)機(jī)器 B 上,機(jī)器 B 上是沒有存該用戶信息的,所以也找不到 sessionId,因此 sessionId 不應(yīng)該存儲(chǔ)在服務(wù)器上。這個(gè)時(shí)候redis/Memcached便出來解決該問題了,可以簡單的理解它們?yōu)橐粋€(gè)緩存數(shù)據(jù)庫
          當(dāng)我們把 sessionId 集中存儲(chǔ)到一個(gè)獨(dú)立的緩存服務(wù)器上,所有的機(jī)器根據(jù) sessionId 到這個(gè)緩存系統(tǒng)里去獲取用戶信息和認(rèn)證。那么問題就迎刃而解了。

          Cookie-session 工作原理流程圖

          5e91e64f76448867b7753bd7a5255ddc.webp
          根據(jù)其工作原理,你有沒有發(fā)現(xiàn)這個(gè)方式會(huì)存在一個(gè)什么樣的問題?
          那就是增加了單點(diǎn)登錄失敗的可能性,如果負(fù)責(zé) session 的機(jī)器掛了, 那整個(gè)登錄也就掛了。但是一般在項(xiàng)目里,負(fù)責(zé) session 的機(jī)器也是有多臺(tái)機(jī)器的集群進(jìn)行負(fù)載均衡,增加可靠性。

          思考:
          假如服務(wù)器重啟的話,用戶信息會(huì)丟失嗎?
          Redis 等緩存服務(wù)器也是有個(gè)集群的,假設(shè)某一臺(tái)服務(wù)重啟了,會(huì)從其他運(yùn)行的服務(wù)器中查找用戶信息,那假設(shè)真的某一次所有服務(wù)器全都崩潰了,怎么辦呢?大概的應(yīng)對(duì)策略就是,存儲(chǔ)在內(nèi)存中的用戶信息會(huì)定期刷到主機(jī)硬盤中以持久化數(shù)據(jù),即便丟失,也只會(huì)丟失重啟的那幾分鐘內(nèi)的用戶數(shù)據(jù)。

          Cookie-session 局限性

          1、依賴 Cookie,用戶可以在瀏覽器端禁用 Cookie
          2、不支持跨端兼容 app 等
          3、業(yè)務(wù)系統(tǒng)不停的請(qǐng)求緩存服務(wù)器查找用戶信息,使得內(nèi)存開銷增加,服務(wù)器壓力過大
          4、服務(wù)器是有狀態(tài)的,如果是沒有緩存服務(wù)器的方式,擴(kuò)容就非常困難,需要在多臺(tái)服務(wù)器中瘋狂復(fù)制 sessionId
          5、存在單點(diǎn)登錄失敗的可能性

          第二篇章


          SSO(單點(diǎn)登錄)三種類型

          單點(diǎn)登錄(Single Sign On),簡稱為 SSO。隨著企業(yè)的發(fā)展,一個(gè)大型系統(tǒng)里可能包含 n 多子系統(tǒng),用戶在操作不同的系統(tǒng)時(shí),需要多次登錄,很麻煩,單點(diǎn)登錄就是用來解決這個(gè)問題的,在多個(gè)應(yīng)用系統(tǒng)中,只需要登錄一次,就可以訪問其他相互信任的應(yīng)用系統(tǒng)。
          8b5b6df6e57119b544fbfb861d42a864.webp
          之前我們說過,單點(diǎn)登錄是基于 cookie 同頂域共享的,那按照不同的情況可分為以下 3 種類型。
          1、同一個(gè)站點(diǎn)下;
          2、系統(tǒng)在相同的頂級(jí)域名下;
          3、各子系統(tǒng)屬于不同的頂級(jí)域名

          一般情況下一個(gè)企業(yè)有一個(gè)頂級(jí)域名,前面講過了,同一個(gè)站點(diǎn)和相同頂級(jí)域下的單點(diǎn)登錄是利用了 Cookie 頂域共享的特性,相信大家已經(jīng)明白這個(gè)流程,不再贅述。但如果是不同域呢?不同域之間 Cookie 是不共享的,怎么辦?

          CAS(中央認(rèn)證服務(wù))原理

          這里我們就要說一說 CAS(中央認(rèn)證服務(wù) )流程了,這個(gè)流程是單點(diǎn)登錄的標(biāo)準(zhǔn)流程。它借助一個(gè)單獨(dú)的系統(tǒng)專門做認(rèn)證用,以下成為SSO系統(tǒng)。
          它的流程其實(shí)跟 Cookie-session 模式是一樣的,單點(diǎn)登錄等于說是每個(gè)子系統(tǒng)都擁有一套完整的 Cookie-session 模式,再加上一套 Cookie-session 模式的 SSO 系統(tǒng)。
          c148e32c4082a925922bbcbd2f57afe8.webp
          用戶訪問系統(tǒng) a,需登錄的時(shí)候跳到 SSO 系統(tǒng),在 SSO 系統(tǒng)里通過賬號(hào)密碼認(rèn)證之后,SSO 的服務(wù)器端保存 session,,并生成一個(gè) sessionId 返回給 SSO 的瀏覽器端,瀏覽器端寫入 SSO 域下的 Cookie,并生成一個(gè)生成一個(gè) ST,攜帶該 ST 傳入系統(tǒng) a,系統(tǒng) a 用這個(gè) ST 請(qǐng)求 SSO 系統(tǒng)做校驗(yàn),校驗(yàn)成功后,系統(tǒng) a 的服務(wù)器端將登錄狀態(tài)寫入 session 并種下系統(tǒng) a 域下的 Cookie。之后系統(tǒng) a 再做登錄驗(yàn)證的時(shí)候,就是同域下的認(rèn)證了。
          這時(shí),用戶訪問系統(tǒng) b,當(dāng)跳到 SSO 里準(zhǔn)備登錄的時(shí)候發(fā)現(xiàn) SSO 已經(jīng)登錄了,那 SSO 生成一個(gè) ST,攜帶該 ST 傳入系統(tǒng) b,系統(tǒng) b 用這個(gè) ST 請(qǐng)求 SSO 系統(tǒng)做校驗(yàn),校驗(yàn)成功后,系統(tǒng) b 的服務(wù)器端將登錄狀態(tài)寫入 session 并設(shè)置系統(tǒng) b 域下的 Cookie。可以看得出,在這個(gè)流程里系統(tǒng) b 就不需要再走登錄了。
          關(guān)于“跳到 SSO 里準(zhǔn)備登錄的時(shí)候發(fā)現(xiàn) SSO 已經(jīng)登錄了”,這個(gè)是怎么做的呢,這就涉及 Oauth2 授權(quán)機(jī)制了,在這里就不展開講,簡單提個(gè)思路,就是在系統(tǒng) b 向 SSO 系統(tǒng)跳轉(zhuǎn)的時(shí)候讓它從系統(tǒng) a 跳轉(zhuǎn),攜帶系統(tǒng) a 的會(huì)話信息跳到 SSO,再通過重定向回系統(tǒng) b。
          關(guān)于 Oauth2,可移步阮一峰 的《OAuth 2.0 的四種方式》。

          第三篇章

          我們已經(jīng)分析過 Cookie-session 的局限性了,還有沒有更徹底的解決辦法呢?既然 SSO 認(rèn)證系統(tǒng)的存在會(huì)增加單點(diǎn)失敗的可能性,那我們是不是索性不要它?這就是去中心化的思路,即省去用來存儲(chǔ)和校驗(yàn)用戶信息的緩存服務(wù)器,以另外的方式在各自系統(tǒng)中進(jìn)行校驗(yàn)。實(shí)現(xiàn)方式簡單來說,就是把 session 的信息全部加密到 Cookie 里,發(fā)送給瀏覽器端,用 cpu 的計(jì)算能力來換取空間。

          Json Web Token 模式

          服務(wù)端不保存 sessionId,用戶登錄系統(tǒng)后,服務(wù)器給他下發(fā)一個(gè)令牌(token),下一次用戶再次通過 Http 請(qǐng)求訪問服務(wù)器的時(shí)候, 把這個(gè) token 通過 Http header 或者 url 帶過來進(jìn)行校驗(yàn)。為了防止別人偽造,我們可以把數(shù)據(jù)加上一個(gè)只有自己才知道的密鑰,做一個(gè)簽名,把數(shù)據(jù)和這個(gè)簽名一起作為 token 發(fā)送過去。這樣我們就不用保存 token 了,因?yàn)榘l(fā)送給用戶的令牌里,已經(jīng)包含了用戶信息。當(dāng)用戶再次請(qǐng)求過來的時(shí)候我用同樣的算法和密鑰對(duì)這個(gè) token 中的數(shù)據(jù)進(jìn)行加密,如果加密后的結(jié)果和 token 中的簽名一致,那我們就可以進(jìn)行鑒權(quán),并且也能從中取得用戶信息。
          75c88ba223e0094bde3e94389623eaf9.webp
          對(duì)于服務(wù)端來說,這樣只負(fù)責(zé)生成 token , 然后驗(yàn)證 token ,不再需要額外的緩存服務(wù)器存儲(chǔ)大量的 session,當(dāng)面對(duì)訪問量增加的情況,我們只需要針對(duì)訪問需求大的服務(wù)器進(jìn)行擴(kuò)容就好了,比擴(kuò)充整個(gè)用戶中心的服務(wù)器更節(jié)省。
          假如有人篡改了用戶信息,但是由于密鑰是不知道的,所以 token 中的簽名和被篡改后客戶端計(jì)算出來的簽名肯定是不一致的,也會(huì)認(rèn)證失敗,所以不必?fù)?dān)心安全問題。
          關(guān)于 token 的時(shí)效性,是這樣做的,首次登陸根據(jù)賬號(hào)密碼生成一個(gè) token,之后的每次請(qǐng)求,服務(wù)端更新時(shí)間戳發(fā)送一個(gè)新的 token,客戶端替換掉原來的 token。

          JWT 工作原理流程圖

          5cebbaa887866c366b291561c8442f62.webp

          JWT 有什么優(yōu)劣勢(shì)

          弊端
          1.jwt 模式的退出登錄實(shí)際上是假的登錄失效,因?yàn)橹皇菫g覽器端清除 token 形成的假象,假如用之前的 token 只要沒過期仍然能夠登陸成功
          2.安全性依賴密鑰,一旦密鑰暴露完蛋
          3.加密生成的數(shù)據(jù)比較長,相對(duì)來說占用了更大的流量

          優(yōu)點(diǎn)
          1.不依賴 Cookie,可跨端跨程序應(yīng)用,支持移動(dòng)設(shè)備
          2.相對(duì)于沒有單點(diǎn)登錄的 cookie-session 模式來說非常好擴(kuò)展
          3.服務(wù)器保持了無狀態(tài)特性,不需要將用戶信息存在服務(wù)器或 Session 中
          4.對(duì)于單點(diǎn)登錄需要不停的向 SSO 站點(diǎn)發(fā)送驗(yàn)證請(qǐng)求的模式節(jié)省了大量請(qǐng)求

          前往微醫(yī)互聯(lián)網(wǎng)醫(yī)院在線診療平臺(tái),快速問診,3分鐘為你找到三甲醫(yī)生。

          • 后臺(tái)回復(fù):typescript,獲取我寫的 typescript 系列文章,絕對(duì)精品
          • 后臺(tái)回復(fù):電子書,自動(dòng)獲取我為大家整理的大量經(jīng)典電子書,省去你篩選以及下載的時(shí)間
          • 后臺(tái)回復(fù):不一樣的前端,自動(dòng)獲取精選優(yōu)質(zhì)前端文章。
          • 后臺(tái)回復(fù):算法,自動(dòng)獲取精選算法文章。另外也可關(guān)注我的另外一個(gè)專注算法的公眾號(hào)力扣加加
          • 后臺(tái)回復(fù):每日一薦,自動(dòng)獲取我為大家總結(jié)的每日一薦月刊,內(nèi)含精品文章,實(shí)用技巧,高效工具等等

          a53191c7eb9ec47b056df5d23dfbb584.webp


          瀏覽 37
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲熟女乱色综合亚洲AV | 精品18禁 | 日韩无码性爱 | 少妇久久久久久 | 日本成人性爱视频网站 |