<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    微服務(wù)Token鑒權(quán)設(shè)計的幾種方案

    共 2756字,需瀏覽 6分鐘

     ·

    2024-04-11 09:06

    1e9b69c08cab4033f642b8a2fc453563.webp

    javapub.net.cn

    作者:JavaPub
    編程學(xué)習(xí)一條龍:http://luxian.javapub.net.cn

        

    原文:juejin.cn/post/7329352197837029385


    Token透傳(不推薦)

    剛開始接觸微服務(wù)時網(wǎng)上給的方案大都數(shù)是通過透傳Token做鑒權(quán),但我認(rèn)為這種方式不是很妥當(dāng)。接著往下看:

    de703925c255921a7f1f81c653284c7e.webp


    這種方式通過透傳Token使得各微服務(wù)都能獲取到當(dāng)前登錄人信息,在代碼編寫上確實可能會方便,但我認(rèn)為這不是一種很好的設(shè)計方式。

    原因一:內(nèi)部API與外部API混合在一起不太好區(qū)分。

    原因二:內(nèi)部調(diào)用的微服務(wù)API因該具備無狀態(tài)性質(zhì),這樣才能保證方法的原子性以提高代碼復(fù)用率。

    換句話說:B服務(wù)提供API時不因該關(guān)心當(dāng)前是否為登錄狀態(tài),登錄狀態(tài)應(yīng)該由路由中的第一個服務(wù)校驗維護(hù),在調(diào)用后續(xù)服務(wù)時應(yīng)該顯示的傳入相關(guān)參數(shù)。比如以下場景:

    場景一:用戶簽到添加積分

    場景二:后臺管理員給用戶手動添加積分

    場景三:分布式調(diào)度批量增加用戶積分

    根據(jù)需求積分服務(wù)提供了一個給用戶添加積分的API,如果你的API是通過獲取的當(dāng)前登錄用戶ID增加的積分,那么面對場景二時你需要重新編寫一個給用戶添加積分的API,因為當(dāng)前登錄的是后臺管理員而不是用戶(代碼復(fù)用率較低)

    不透傳數(shù)據(jù),顯示的提供入?yún)?/strong>

    46d5bda6a2aee8fe9bdd3b92a02c1bb2.webp


    路由到達(dá)的第一個服務(wù)已經(jīng)對Token進(jìn)行了解析認(rèn)證并將userId顯示的傳遞給了后續(xù)服務(wù),后續(xù)服務(wù)不需要再對token進(jìn)行解析認(rèn)證。根據(jù)1.1的三個場景只需要提供一個入?yún)瑄serId的API,保證了函數(shù)的原子性提供代碼復(fù)用率。

    注意: 提供的API不能暴露給外網(wǎng),我們需要在路徑上做區(qū)分,避免外網(wǎng)非法訪問內(nèi)部API。我們可以訂好內(nèi)部調(diào)用API路徑規(guī)則,如: /api/inside/\*\* 。在網(wǎng)關(guān)層拒絕內(nèi)部調(diào)用API請求的訪問。

    統(tǒng)一授權(quán)

    統(tǒng)一授權(quán)是指:將API鑒權(quán)集中在 應(yīng)用網(wǎng)關(guān)

    Fegin內(nèi)部調(diào)用方式

    Spring Cloud Gateway  + Fegin內(nèi)部調(diào)用,集中在Gateway上做統(tǒng)一認(rèn)證鑒權(quán),鑒權(quán)后在請求頭中添加鑒權(quán)后的信息轉(zhuǎn)發(fā)給后續(xù)服務(wù),如:userId等。。。

    986e8e1c2621b18ab24d65eec0178575.webp


    缺點:A服務(wù)調(diào)用B服務(wù)時,B服務(wù)需要寫一個內(nèi)部調(diào)用的Controller接口A服務(wù)才能通過Fegin調(diào)用到B服務(wù),增加了代碼量(這里的設(shè)計方案是內(nèi)部調(diào)用與外部調(diào)用Controller是分開的)

    Dubbo內(nèi)部調(diào)用方式

    Spring Cloud Gateway + Dubbo內(nèi)部調(diào)用,集中在Gateway上做統(tǒng)一認(rèn)證鑒權(quán),鑒權(quán)后在請求頭中添加鑒權(quán)后的信息轉(zhuǎn)發(fā)給后續(xù)服務(wù),如:userId等。。。

    優(yōu)點:與第一種相比不需要額外編寫一個Controller接口,只有本地service與遠(yuǎn)程DubboService的區(qū)別,代碼更簡潔。

    缺點:項目技術(shù)棧略微增加了復(fù)雜度。

    0989af231134372a158b5f41c01c31de.webp


    Spring Boot Web + Dubbo內(nèi)部調(diào)用方式

    這里的設(shè)計方案直接去掉了Gateway,直接使用了一個Spring Boot Web項目來代替Gateway。但需要注意的是應(yīng)該將Web項目的容器換成Undertow,因為Tomcat是阻塞式的容器,不換也不是不行,但吞吐量可能會少一下,Undertow是非阻塞式的容器,可以與Gateway到達(dá)相同的效果。(非阻塞式:當(dāng)請求為線程進(jìn)入阻塞狀態(tài)時,當(dāng)前線程會被掛起,當(dāng)前的計算資源會去做別的事情,當(dāng)被掛起的線程收到響應(yīng)時才會被繼續(xù)執(zhí)行,壓榨CPU用更少的資源做更多的事情,但并不會提升性能)

    因為去掉了Gateway我們需要將所有服務(wù)的Controller集成到Web應(yīng)用,然后在這個Web應(yīng)用上做統(tǒng)一認(rèn)證授權(quán)。如果將所有代碼寫到Web應(yīng)用中,這樣可能不合適,我們可以選擇每個服務(wù)創(chuàng)建一個Controller模塊,Web網(wǎng)關(guān)服務(wù)只有一個啟動類,通過依賴的方式集成所有服務(wù)的Controller。

    優(yōu)點:簡化了項目結(jié)構(gòu),所有服務(wù)只有service代碼。性能壓測時不用考慮Gateway的線程池使用情況,業(yè)務(wù)服務(wù)只需要考慮Dubbo線程池的使用情況。

    缺點:沒辦法通過配置中心動態(tài)調(diào)整路由。比如說增加了一個服務(wù)Gateway可以不重啟通過配置中心增加路由配置即可。

    16574a6b057423dedb037c2532105374.webp


    非統(tǒng)一授權(quán)

    非統(tǒng)一授權(quán):不在應(yīng)用網(wǎng)關(guān)上集成鑒權(quán),網(wǎng)關(guān)只有單一的路由轉(zhuǎn)發(fā)業(yè)務(wù)。各位服務(wù)都有自己的鑒權(quán)方式,當(dāng)然也可以通過jar包的方式統(tǒng)一各服務(wù)的鑒權(quán)方式。

    常規(guī)模式

    通過編寫通用的鑒權(quán)模塊,各服務(wù)集成該模塊。該模塊具備以下功能:

    1. JWT Token解析
    2. 權(quán)限校驗攔截
    3. 緩存(本地緩存\Redis緩存)

    這種模式更適合大型項目團(tuán)隊,可能各微服務(wù)都由一個項目組負(fù)責(zé)。各服務(wù)維護(hù)自己的權(quán)限規(guī)則(這里指的是權(quán)限規(guī)則數(shù)據(jù),規(guī)則是統(tǒng)一的)

    76186bf891dae3ae8dc5fdbd6fc28e4e.webp


    該模式下由于應(yīng)用網(wǎng)關(guān)比較輕量級,不再涉及復(fù)雜的鑒權(quán)流程,使得項目部署可以更靈活,當(dāng)我們使用K8S部署項目時,我們可以將應(yīng)用網(wǎng)關(guān)替換成K8S中的Ingress網(wǎng)關(guān)。

    我們先看常規(guī)模式部署在K8S中完整的鏈路:

    f31fcac853d3c37edd95b2e35ed2dde7.webp


    當(dāng)用戶訪問時會先到達(dá)K8S Ingress網(wǎng)關(guān)通過應(yīng)用網(wǎng)關(guān)Service的負(fù)載均衡調(diào)用應(yīng)用網(wǎng)關(guān),應(yīng)用網(wǎng)關(guān)需要通過注冊中心獲取服務(wù)注冊列表,通過服務(wù)注冊列表負(fù)載均衡到后續(xù)服務(wù)。

    與K8S集成

    我們再來看看將應(yīng)用網(wǎng)關(guān)替換成K8S中的Ingress網(wǎng)關(guān)的完整鏈路:

    52b4617f4fd8a9ac9878cd9c927fb701.webp


    這里不僅只是去掉了應(yīng)用網(wǎng)關(guān),同時我們通過K8S Service 負(fù)載均衡的能力去掉了注冊中心。減少了我們部署微服務(wù)時還要額外搭建一套注冊中心。同時減少了一層沒必要的轉(zhuǎn)發(fā)。至于K8S中的Service,大家可以理解成一個本地的host假域名,比如我們在K8S給商品創(chuàng)建一個Service,名稱為:goods-svc。那么我們可以通過goods-svc直連。如:

    1. http://goods-svc:8080/api/goods/info/10001
    2. dubbo://goods-svc:20880

    方案沒有對錯,選擇適合自己的就是最好的。

        
          
      

    往期干貨筆記整理

    瀏覽 37
    點贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報
    評論
    圖片
    表情
    推薦
    點贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    色色大香蕉 | 亚洲欧洲在线免费观看 | 三级片网站入口 | 综合五月激情网 | 欧美福利在线 |