王 鋒,劉俊波
(中國電子科技集團(tuán)公司第30 研究所,四川 成都 610041)
當(dāng)前WEB 系統(tǒng)開發(fā)多采用前后端分離模式。前端組件化、工程化,后端數(shù)據(jù)化;前端實現(xiàn)人機(jī)交互邏輯,提供業(yè)務(wù)數(shù)據(jù)展示,后端為前端提供業(yè)務(wù)數(shù)據(jù)支撐;前后端通過RESTful 接口進(jìn)行數(shù)據(jù)交互。這種模式下前后端架構(gòu)分離,降低了人員要求,開發(fā)效率高,給系統(tǒng)設(shè)計與開發(fā)帶來了極大便利。前后端分離后,一個系統(tǒng)被分割為了兩個獨(dú)立的工程。用戶身份不同時,前端需要根據(jù)后端權(quán)限數(shù)據(jù)實現(xiàn)模塊鑒權(quán),同時在多個WEB 系統(tǒng)集成部署時,需要為這些系統(tǒng)提供統(tǒng)一的界面呈現(xiàn),解決系統(tǒng)之間的頁面組件互相調(diào)用、用戶身份的單點登錄、后端資源請求權(quán)限檢測等問題。為此,本文設(shè)計了一種針對前后端分離模式下的WEB 系統(tǒng)集成方案。
前后端分離模式下,前端和后端是獨(dú)立架構(gòu),互不干涉。不同系統(tǒng)后端服務(wù)采用的語言、框架往往不同,如果要在這些不同系統(tǒng)內(nèi)部實現(xiàn)統(tǒng)一模式的身份認(rèn)證和權(quán)限檢測,極其困難且代價太高。為此借用微服務(wù)的架構(gòu)模型,在后端服務(wù)前面增加一個獨(dú)立的API 網(wǎng)關(guān)模塊[1],專門為這些使用不同語言框架開發(fā)的系統(tǒng)解決如單點登錄、資源鑒權(quán)等共性問題。
集成方案將系統(tǒng)分為前端展示層、中間接入層和后端業(yè)務(wù)服務(wù)層3 層,架構(gòu)如圖1 所示。展示層即為前后端分離后的純前端,采用vue 框架。中間接入層為API 網(wǎng)關(guān)模塊,通常部署在后端業(yè)務(wù)系統(tǒng)前面,負(fù)責(zé)用戶身份認(rèn)證、權(quán)限檢測和路由轉(zhuǎn)發(fā)等功能。API 網(wǎng)關(guān)與業(yè)務(wù)系統(tǒng)之間采用RESTful 進(jìn)行交互[2]。后端業(yè)務(wù)邏輯層為業(yè)務(wù)系統(tǒng)的后端服務(wù)。
圖1 總體架構(gòu)
WEB 前端已經(jīng)從傳統(tǒng)的MVC 模式進(jìn)一步發(fā)展為MVVM 模式[3]。系統(tǒng)采用vue+vue-router+iview UI 搭建前端基礎(chǔ)開發(fā)框架。vue 是一套用于構(gòu)建用戶界面的漸進(jìn)式框架[4],具有易用、靈活等特性,便于與第三方庫和既有項目整合,是整個前端框架的技術(shù)核心。vue-router 是針對vue 開發(fā)的路由插件,作為vue 的官方的路由管理器,提供單頁應(yīng)用服務(wù)。iview UI 是一套基于vue 的高質(zhì)量UI 組件,提供如表單控件、按鈕、導(dǎo)航菜單、表格、對話框等常用組件,能夠滿足絕大部分WEB 應(yīng)用場景。前后端交互請求工具采用axios,可以自定義攔截器、處理攜帶票據(jù)、cookie、自動取消請求、防止CSRF/XSRF 等功能。
一個業(yè)務(wù)系統(tǒng)由許多業(yè)務(wù)組件構(gòu)成,每個業(yè)務(wù)組件就是一個獨(dú)立的模塊,可以單獨(dú)打包使用。組件可以進(jìn)一步劃分為更細(xì)小的組件,這里稱為微組件。獨(dú)立打包的微組件實際就是一個WEB widget,具有“高內(nèi)聚、低耦合”的優(yōu)點[5]。業(yè)務(wù)系統(tǒng)之間可以調(diào)用對方系統(tǒng)的組件來使用,如圖2 所示。
圖2 前端頁面組件調(diào)用
采用vue-custom-element 進(jìn)行業(yè)務(wù)組件封裝。圍繞vue 組件的小包裝器,能夠在vue、react、angular 這些前端框架中提供無縫的使用方式。頁面中只需要引用相應(yīng)的javaScript 文件,然后在HTML標(biāo)簽中引入相應(yīng)的標(biāo)記即可渲染出vue 組件,為不同業(yè)務(wù)系統(tǒng)組件的相互調(diào)用提供解決方案。
組件開發(fā)時,為方便每個業(yè)務(wù)組件單獨(dú)打包,需要在項目中為該業(yè)務(wù)組件添加一個打包入口文件。該文件的命名方式應(yīng)該與系統(tǒng)名稱和業(yè)務(wù)名稱相呼應(yīng)。例如,某監(jiān)控系統(tǒng)的設(shè)備管理模塊對應(yīng)的打包入口文件命名為monitor-dev,該業(yè)務(wù)組件打包后對應(yīng)文件名稱也為monitor-dev.js。在其他系統(tǒng)中如果需要引用該業(yè)務(wù)模塊,引入monitor-dev.js 以及組件對應(yīng)的HTML 標(biāo)記即可。HTML 標(biāo)記在組件的打包入口文件中定義,標(biāo)記名稱應(yīng)該和入口名稱保持一致,如vue.customElement(‘widget-monitordev’,Dev),其中“widget”表示這個一個vue 微組件,monitor 表示該組件是監(jiān)控系統(tǒng)所有,Dev 表示對應(yīng)的vue 業(yè)務(wù)組件,在HTML 中引入<widgetmonitor-dev></widget-monitor-dev>標(biāo)記對即可加載對應(yīng)的業(yè)務(wù)組件。業(yè)務(wù)組件加載及工作流程如圖3所示。
①登錄系統(tǒng);
②獲取認(rèn)證token,存儲到sessionStorage;
③使用系統(tǒng)定義的組件加載方法,通過token加載業(yè)務(wù)系統(tǒng)b 的monitor_dev 組件;
④業(yè)務(wù)系統(tǒng)b 的組件加載接口向API 網(wǎng)關(guān)驗證token 合法性;
⑤下載monitor_dev.js;
⑥Monitor_dev 組件使用token 向業(yè)務(wù)系統(tǒng)b 請求業(yè)務(wù)數(shù)據(jù);
⑦業(yè)務(wù)系統(tǒng)b 的業(yè)務(wù)模塊向API 網(wǎng)關(guān)驗證token 合法性;
⑧業(yè)務(wù)系統(tǒng)b 向客戶端組件返回業(yè)務(wù)數(shù)據(jù)。
圖3 業(yè)務(wù)組件加載及工作流程
前端鑒權(quán)存在兩個方面的需求:一是用戶是否具備組件顯示執(zhí)行權(quán)限;二是組件向后端發(fā)起數(shù)據(jù)請求時后端返回的權(quán)限結(jié)果處理。
針對組件在前端是否能夠顯示執(zhí)行,需要根據(jù)后端給出的權(quán)限進(jìn)行判別?;趘ue 的標(biāo)簽指令自定義了一個權(quán)限判斷指令v-permission,該指令會根據(jù)后端返回的用戶接口請求白名單進(jìn)行匹配,只有當(dāng)該組件所使用接口在白名單中,組件才會被顯示和執(zhí)行。比如,一個設(shè)備添加按鈕組件devadd,頁面引用該標(biāo)簽時增加相應(yīng)的v-permission指 令,<widget-dev-add v-permission></widget-devadd>,那么前端就會對組件顯示進(jìn)行權(quán)限鑒別。只有當(dāng)前用戶被允許使用設(shè)備添加接口時,該按鈕才會在頁面中顯示出來,否則頁面會隱藏此添加按鈕。
組件向后端發(fā)起數(shù)據(jù)請求的權(quán)限結(jié)果處理,會通過axios 自定義攔截器實現(xiàn)。axios 攔截器分為請求前攔截和請求后攔截兩種。由于請求結(jié)果是后端返回,所以使用請求后攔截。在這個攔截器中,針對請求結(jié)果的權(quán)限處理可以進(jìn)行統(tǒng)一定義,使得系統(tǒng)集成時能有一個統(tǒng)一的異常處理模式,從而提高用戶體驗。
后端采用一個專用的API 網(wǎng)關(guān)模塊,負(fù)責(zé)業(yè)務(wù)系統(tǒng)注冊、用戶認(rèn)證和資源訪問鑒權(quán)等方面的集成業(yè)務(wù),使得業(yè)務(wù)系統(tǒng)可以專注于業(yè)務(wù)開發(fā)。
業(yè)務(wù)系統(tǒng)需要在API 網(wǎng)關(guān)上注冊其基本信息和資源信息。基本信息應(yīng)包括系統(tǒng)標(biāo)識、系統(tǒng)地址和端口等;資源信息主要包括菜單定義及接口信息表;這些資源信息有規(guī)范化的格式,多采用xml 數(shù)據(jù)文件格式。API 網(wǎng)關(guān)擁有這些信息后,可以由管理員為用戶訪問配置資源授權(quán)。
API 網(wǎng)關(guān)模塊存在兩種部署模式:一是所有業(yè)務(wù)系統(tǒng)部署在API 網(wǎng)關(guān)模塊后面,資源請求必須通過API 網(wǎng)關(guān)模塊轉(zhuǎn)發(fā),稱為斷路式部署模式;二是業(yè)務(wù)系統(tǒng)可能部署在API 網(wǎng)關(guān)模塊外面,資源請求可以不經(jīng)過網(wǎng)關(guān)直接到達(dá)業(yè)務(wù)系統(tǒng),稱為旁路式部署模式。無論選擇哪種部署模式,在多個系統(tǒng)集成時都希望能實現(xiàn)單點登錄模式,即一次登錄認(rèn)證后對多個業(yè)務(wù)系統(tǒng)都有效,訪問其他業(yè)務(wù)系統(tǒng)時無需再次登錄認(rèn)證。針對這兩種部署模式,為實現(xiàn)單點登錄,對應(yīng)有兩種登錄認(rèn)證流程。
3.2.1 斷路式部署認(rèn)證
認(rèn)證流程如圖4 所示。
圖4 斷路式部署認(rèn)證流程
A:瀏覽器發(fā)起認(rèn)證登錄;
B:API 網(wǎng)關(guān)認(rèn)證(根據(jù)系統(tǒng)實際認(rèn)證協(xié)議要求確定)成功后,基于JWT 格式生成認(rèn)證票據(jù)及刷新票據(jù),并返回給瀏覽器客戶端,而瀏覽器客戶端將認(rèn)證票據(jù)及刷新票據(jù)存儲在客戶端(Session Storage);
C:瀏覽器訪問任意業(yè)務(wù)系統(tǒng),帶上認(rèn)證票據(jù),API 網(wǎng)關(guān)驗證票據(jù),解析出用戶身份信息;
D:API 網(wǎng)關(guān)將請求及用戶信息轉(zhuǎn)發(fā)給相應(yīng)業(yè)務(wù)系統(tǒng)。
3.2.2 旁路式部署認(rèn)證
認(rèn)證流程如圖5 所示。
圖5 旁路式部署認(rèn)證流程
A:瀏覽器訪問業(yè)務(wù)系統(tǒng),認(rèn)證登錄;
B:業(yè)務(wù)系統(tǒng)將請求重定向到API 網(wǎng)關(guān)的認(rèn)證地址;
C:瀏覽器向API 網(wǎng)關(guān)認(rèn)證地址發(fā)起認(rèn)證請求;
D:認(rèn)證(根據(jù)系統(tǒng)實際認(rèn)證協(xié)議要求確定)成功后,API 網(wǎng)關(guān)向瀏覽器客戶端返回認(rèn)證授權(quán)碼;
E:瀏覽器將認(rèn)證授權(quán)碼返回給業(yè)務(wù)系統(tǒng);
F:業(yè)務(wù)系統(tǒng)將認(rèn)證授權(quán)碼發(fā)送給API 網(wǎng)關(guān)認(rèn)證,對授權(quán)碼有效性進(jìn)行驗證;
G:API 網(wǎng)關(guān)驗證授權(quán)碼合法后生成認(rèn)證票據(jù)及刷新票據(jù),并將驗證結(jié)果及票據(jù)返回給業(yè)務(wù)系統(tǒng);
H:業(yè)務(wù)系統(tǒng)獲得驗證結(jié)果和票據(jù)后認(rèn)證完成,將請求資源、認(rèn)證票據(jù)和刷新票據(jù)返回給瀏覽器客戶端。
由于API 網(wǎng)關(guān)部署存在兩種模式,因此資源訪問鑒權(quán)也存在兩種方式。
3.3.1 斷路式部署模式鑒權(quán)
斷路部署模式下,前端發(fā)起業(yè)務(wù)請求時需帶上認(rèn)證時返回的token 票據(jù)。API 網(wǎng)關(guān)接收請求后,先對token 合法性做驗證,驗證過程需要解析出對應(yīng)的終端用戶身份信息。驗證成功后,基于該用戶信息與需要訪問的資源進(jìn)行訪問授權(quán)判斷,判斷完成后基于資源URI 進(jìn)行路由轉(zhuǎn)發(fā),將用戶信息和資源請求轉(zhuǎn)發(fā)給最終的業(yè)務(wù)系統(tǒng)。
3.3.2 旁路式部署模式鑒權(quán)
旁路式部署模式下,前端發(fā)起資源請求首先到達(dá)業(yè)務(wù)系統(tǒng)。業(yè)務(wù)系統(tǒng)需要向API 網(wǎng)關(guān)驗證請求中token 票據(jù)的合法性,API 網(wǎng)關(guān)將驗證結(jié)果和票據(jù)解析出來的用戶信息一并返回給業(yè)務(wù)系統(tǒng)。業(yè)務(wù)系統(tǒng)基于訪問資源和用戶信息,向API 網(wǎng)關(guān)發(fā)起資源訪問鑒權(quán),鑒權(quán)成功后再調(diào)用響應(yīng)的業(yè)務(wù)處理模塊向前端返回資源信息。
本系統(tǒng)集成方案解決了前后端分離模式下多個業(yè)務(wù)系統(tǒng)集成部署時需要解決的各種問題,包括前端的頁面統(tǒng)一框架、頁面互相調(diào)用、頁面鑒權(quán)處理等,以及后端服務(wù)的用戶身份單點登錄認(rèn)證、資源訪問權(quán)限檢測等。采用本方案后,業(yè)務(wù)系統(tǒng)能專注于用戶業(yè)務(wù)開發(fā),集成部署簡單方便且節(jié)約了成本,適用于前后端分離模式下各種語言和框架開發(fā)的WEB 系統(tǒng)。