程慶華
(河南省水文水資源局)
隨著信息化技術的不斷推進,水文數據也由以紙質年鑒轉化為以國標數據庫為主要成果形式。形式的改變,也促進了水文數據的廣泛應用。面對各行各業對日益增漲的各種水文數據需求,亟待建立一套完善的水文數據共享系統,有序、安全和高可靠性的解決水文數據共享使用問題。文章采用基于API 網關技術,通過JWT 認證,建立安全高效的水文數據共性系統。
在面對各種水文數據使用需求時,采用完全開放的數據形式是不安全的,也是低效的,更遑論開放紙質年鑒查詢形式,非常不利于水文數據使用,發揮其重要的國民經濟建設作用。因此,要建立水文數據共性系統必須至少滿足以下三個條件:一是個性化使用。按照使用者的需求,在水文數據安全范圍內按需使用水文數據;二是身份認證。根據不同的使用者,提供不同級別和深度的水文數據,需要由一個完善的身份認證體系;三是滿足海量數據需求。水文數據的使用涉及各行各業,任意時刻,因此需要建立一套滿足分布式各類用戶的數據需求。
基于API 服務網關的水文數據共享系統就是把各種水文數據需求,按照API 服務模式,以JOSN 提供給數據獲取者。API 服務網關通過分布式服務,提供跨域數據安全訪問,利用JWT 認證技術提供身份認證,按需給各個數據獲取者提供數據服務。構建的模型如圖1。
API服務網關是一個服務器,是系統的唯一入口。從面向對象設計的角度看,它與外觀模式類似。API網關封裝了系統內部架構,為每個客戶端提供一個定制的API。它可能還具有其它職責,如身份驗證、監控、負載均衡、緩存、請求分片與管理、靜態響應處理。API 網關方式的核心要點是,所有的客戶端和消費端都通過統一的網關接入微服務,在網關層處理所有的非業務功能。通常,網關也是提供REST/HTTP 的訪問API。服務端通過API-GW注冊和管理服務。

圖1 模型圖
3.1.1 API服務網關的組成
API 服務網關包括三大部分:API 網關、網關控制臺、度量數據采集分析。實際形態各異,可以按需搭建,但肯定少不了API 網關,網關控制臺的功能職責可能會放到服務注冊等地方而沒有單獨抽取出來,至于度量數據采集可能會在整個微服務架構中存一個通用的度量數據采集應用以監控所有類型應用。
對于大多數應用程序而言,API 網關的性能和可擴展性通常都非常重要。因此,API 網關將構建在一個支持異步、I/O 非阻塞的平臺上。Java 系可以使用一種基于NIO 的框架,比如Netty、Vertx、Spring Reactor ,還可以使用Node.js、NGINX Plus。
3.1.2 API服務網關的優缺點
優點:封裝了應用程序的內部結構。客戶端只需要同網關交互,而不必調用特定的服務。API 網關為每一類客戶端提供了特定的API,從而減少客戶端與應用程序間的交互次數,簡化客戶端代碼的處理。
缺點:增加了一個必須開發、部署和維護的高可用組件。還有一個風險是API 網關變成了開發瓶頸。為了暴露每個微服務,開發人員必須更新API 網關。API 網關的更新過程要盡可能地簡單,否則為了更新網關,開發人員將不得不排隊等待。不過,雖然有這些不足,但對于大多數現實世界的應用程序而言使用API 網關是合理的。
3.2.1 JWT 的原理
JWT 有三部分組成:JWT 頭(header)、有效載荷(payload)和簽名哈希(signature)。JWT 的原理是,服務器認證以后,生成一個JSON對象,發回給用戶,如下JSON對象
{
"姓名":"張三",
"角色":"管理員",
"到期時間":"2018年7月1日0點0分"
}
以后,用戶與服務端通信的時候,都要發回這個JSON 對象。服務器完全只靠這個對象認定用戶身份。為了防止用戶篡改數據,服務器在生成這個對象的時候,會加上簽名。
服務器就不保存任何session 數據了,也就是說,服務器變成無狀態了,從而比較容易實現擴展。
3.2.1 JWT的流程
分布式服務離不開用戶認證。一般流程是下面這樣:①用戶向服務器發送用戶名和密碼。②服務器驗證通過后,在當前對話(session)里面保存相關數據,比如:用戶角色、登錄時間等等。③服務器向用戶返回一個session_id,寫入用戶的Cookie。④用戶隨后的每一次請求,都會通過Cookie,將session_id 傳回服務器。⑤服務器收到session_id,找到前期保存的數據,由此得知用戶的身份。
這種模式的問題在于,擴展性(scaling)不好。單機當然沒有問題,如果是服務器集群,或者是跨域的服務導向架構,就要求session 數據共享,每臺服務器都能夠讀取session。一種解決方案是session 數據持久化,寫入數據庫或別的持久層。各種服務收到請求后,都向持久層請求數據。這種方案的優點是架構清晰,缺點是工程量比較大。另外,持久層萬一掛了,就會單點失敗。另一種方案是服務器索性不保存session 數據了,所有數據都保存在客戶端,每次請求都發回服務器。JWT 就是這種方案的一個代表。認證流程如圖2。
3.2.3 JWT的優缺點
①JWT 默認不加密,但可以加密。生成原始令牌后,可以使用改令牌再次對其進行加密。②當JWT未加密方法使一些私密數據無法通過JWT 傳輸。③JWT 不僅可用于認證,還可用于信息交換。善用JWT有助于減少服務器請求數據庫的次數。④JWT 的最大缺點是服務器不保存會話狀態,所以在使用期間不可能取消令牌或更改令牌的權限。也就是說,一旦JWT 簽發,在有效期內將會一直有效。⑤JWT 本身包含認證信息,因此一旦信息泄露,任何人都可以獲得令牌的所有權限。為了減少盜用,JWT 的有效期不宜設置太長。對于某些重要操作,用戶在使用時應該每次都進行身份驗證。⑥為了減少盜用和竊取,JWT 不建議使用HTTP 協議來傳輸代碼,而是使用加密的HTTPS協議進行傳輸。

圖2 認證流程如圖
Spring Cloud Gateway 是Spring Cloud 的一個全新項目,該項目是基于Spring 5.0,Spring Boot 2.0 和Project Reactor 等技術開發的網關,它旨在為微服務架構提供一種簡單有效的統一的API 路由管理方式。Spring Cloud Gateway 作為Spring Cloud 生態系統中的網關,為了提升網關的性能,Spring Cloud Gateway 是基于Web Flux框架實現的,而Web Flux框架底層則使用了高性能的Reactor 模式通信框架Netty。并且基于Filter鏈的方式提供了網關基本的功能,例如:安全,監控/指標,和限流。搭建流程如下:一是引入依賴。主要引入Spring Cloud Gateway 相關依賴;在spring-cloud-starter-gateway 依賴中,會引入Web Flux、Reactor、Netty 等等依賴。二是建立配置文件。在配置文件主要添加Spring Cloud Gateway 相關配置;一是設置網關的服務器端口;二是設置路由配置項,對應Route Definition 數組。路由(Route)是Gateway 中最基本的組件之一,由一個ID、URI、一組謂語(Predicate)、過濾器(Filter)組成。一個請求如果滿足某個路由的所有謂語,則匹配上該路由。三是創建Gateway Application 類,網關的啟動類。
首先在Spring Boot 引入依賴,主要引入JWT 依賴;然后編寫JWT生成與驗證代碼,最后封裝JWT類。通過POST實現跨域應用,可以滿足分布式多種類型用戶的請求和響應。
基于API 服務網關的水文數據共享系統的建立,高效安全的解決了水文數據多種跨域訪問請求,使水文數據不再是“信息孤島”中的封閉數據,使其服務于各行各業的經濟建設。但是在使用過程中,要求API 的封裝必須安全可靠,必要時應該經過Postman的測試才可以投入API網關服務中。