GitHub轻松阅读微服务实战项目流程详解【第二天:API网关的设计与实现】
Two Day
- 1.配置文件精解
- (1)bootstrap.yml文件
- (2)nacos中關(guān)于gateway的配置信息
- (3)applicaton.properties白名單配置
- 2.代碼詳解
- (1)IP限流
- (2)白名單
- (3)Jwt工具類驗證token的有效性
- (4)網(wǎng)關(guān)層面快速失敗返回接口
- (5)微服務(wù)安全認(rèn)證流程
- (6)身份認(rèn)證過濾器實現(xiàn)
github地址:https://github.com/Zealon159/light-reading-cloud
該網(wǎng)關(guān)層面使用Spring GateWay進行實現(xiàn)。
1.配置文件精解
(1)bootstrap.yml文件
spring:application:# 服務(wù)邏輯名稱name: light-reading-cloud-gatewaycloud:nacos:# 配置中心config:server-addr: xxxxxxfile-extension: ymlrefresh: trueshared-dataids: light-reading-cloud-gateway.yml #Data IDnamespace: 4d109a4d-f34d-4e86-9e39-c2d36db24b00 #命名空間# 注冊中心discovery:server-addr: xxxxxnamespace: 4d109a4d-f34d-4e86-9e39-c2d36db24b00(2)nacos中關(guān)于gateway的配置信息
server:port: 8010spring:application:# 服務(wù)邏輯名稱name: light-reading-cloud-gatewaycloud:gateway:discovery:locator:enabled: true #開啟gateway的注冊和發(fā)現(xiàn)lowerCaseServiceId: true #將請求路徑中的服務(wù)名小寫,因為服務(wù)注冊時,Nacos將其轉(zhuǎn)換成大寫了routes: #路由匹配- id: book-center-rpc uri: lb://light-reading-cloud-book #服務(wù)地址predicates: #斷言,匹配路徑和請求方式- Path=/book/**- Method=GETfilters:# 降級配置- name: Hystrixargs:name: fallbackcmdfallbackUri: forward:/fallback #失敗了直接跳轉(zhuǎn)到該路據(jù),這個接口是用戶失敗后快速返回的# 限流配置- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 3 # 每秒允許處理的請求數(shù)量redis-rate-limiter.burstCapacity: 5 # 每秒最大處理的請求數(shù)量key-resolver: "#{@ipKeyResolver}" # 限流策略,對應(yīng)策略的Bean,在gateway配置了該IP的限流策略- id: homepage-rpcuri: lb://light-reading-cloud-homepagepredicates:- Path=/index/**filters:# 降級配置- name: Hystrixargs:name: fallbackcmdfallbackUri: forward:/fallback# 限流配置- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 3redis-rate-limiter.burstCapacity: 5key-resolver: "#{@ipKeyResolver}"- id: account-center-rpcuri: lb://light-reading-cloud-accountpredicates:- Path=/account/**filters:# 降級配置- name: Hystrixargs:name: fallbackcmdfallbackUri: forward:/fallback# 限流配置- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 3redis-rate-limiter.burstCapacity: 5key-resolver: "#{@ipKeyResolver}"hystrix:threadpool:default:coreSize: 20 #并發(fā)執(zhí)行的最大線程數(shù),默認(rèn)10maxQueueSize: 1000 #BlockingQueue的最大隊列數(shù),默認(rèn)值-1queueSizeRejectionThreshold: 400 ribbon:eager-load:enabled: true #開啟Ribbon的饑餓模式, 用于點對點直連問題clients: light-reading-cloud-account,light-reading-cloud-book,light-reading-cloud-homepage(3)applicaton.properties白名單配置
system.properties=/account/user/register,/account/user/login這個本地application.properties是配置的白名單信息,后面會在配置類中進行加載。
2.代碼詳解
(1)IP限流
@Configuration public class RedisRateLimiterConfig {/*** 按客戶端IP限流* Lambda表達式或者匿名函數(shù)都可以快速實現(xiàn)* @return*/@Beanpublic KeyResolver ipKeyResolver() { return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());} }這個ipKeyResolver方法是在gateway配置文件中引用的
(2)白名單
@Data @Component public class SystemPropertiesConfig {/** 請求白名單,引用application.preperties中的屬性 */@Value("${system.properties}")private String whitelist; }(3)Jwt工具類驗證token的有效性
Token比較適用于微服務(wù)的安全認(rèn)證,JWT是一種安全認(rèn)證規(guī)范,token中存儲了用戶信息,只有在服務(wù)端才能根據(jù)密鑰進行解密。
public class JwtUtil {/*** 身份認(rèn)證* @param jwt 令牌* @return 成功狀態(tài)返回200,其它均為失敗*/public static Result<User> validationToken(String jwt) {try {//解析JWT字符串中的數(shù)據(jù),并進行最基礎(chǔ)的驗證Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(jwt).getBody();//如果解析成功,將其封裝到User返回User user = new User();user.setUuid(claims.get("uuid").toString());user.setLoginName(claims.get("loginName").toString());user.setNickName(claims.get("nickName").toString());if (claims.get("phoneNumber") != null) {user.setPhoneNumber(claims.get("phoneNumber").toString());}user.setId(Integer.parseInt(claims.get("id").toString()));user.setHeadImgUrl(claims.get("headImgUrl").toString());return ResultUtil.success(user);} catch (ExpiredJwtException e) {// 已過期令牌return ResultUtil.authExpired();} catch (SignatureException e) {// 偽造令牌return ResultUtil.unAuthorized();} catch (Exception e) {// 系統(tǒng)錯誤return ResultUtil.unAuthorized();}}}(4)網(wǎng)關(guān)層面快速失敗返回接口
public class FallbackController {@GetMapping("/fallback")public Result fallback() {return ResultUtil.fail();} }(5)微服務(wù)安全認(rèn)證流程
常用的認(rèn)證方式主要有三種:Session、HTTP Basic Authentication 和 Token。
- session 是認(rèn)證中最常用的一種方式,也是最簡單的。用戶登錄后將信息存儲在后端,客戶端則通過 Cookie 中的 SessionId 來標(biāo)識對應(yīng)的用戶。
- HTTP Basic Authentication 也就是 HTTP 基本認(rèn)證,它是 HTTP 1.0 提出的一種認(rèn)證機制。HTTP 基本認(rèn)證的原理是客戶端在請求時會在請求頭中增加 Authorization,Authorization 是用戶名和密碼用 Base64 加密后的內(nèi)容。服務(wù)端獲取 Authorization Header 中的用戶名與密碼進行驗證。
- Token 中會存儲用戶的信息,然后通過加密算法進行加密,只有服務(wù)端才能解密,服務(wù)端拿到 Token 后進行解密獲取用戶信息。
Token更適用于微服務(wù)的安全認(rèn)證,本項目采用了token這種認(rèn)證方式,并基于JWT的安全認(rèn)證規(guī)范。
jwt是一種認(rèn)證規(guī)范,它允許我們通過jwt在用戶和服務(wù)器之間傳遞可靠的信息。在通信過程中進行身份認(rèn)證
Ⅰ.用戶進行登錄時,將用戶名和密碼提交給認(rèn)證服務(wù)器,服務(wù)器會驗證用戶提交信息的合法性,如果驗證成功,則會返回一個token,客戶端將token保存起來
Ⅱ.用戶再次請求服務(wù)器時,一般會將token放到請求頭中。當(dāng)請求達到網(wǎng)關(guān)后,會在網(wǎng)關(guān)中對token進行校驗;如果校驗成功,網(wǎng)關(guān)會將其轉(zhuǎn)發(fā)到后端服務(wù)中,轉(zhuǎn)發(fā)時會將用戶信息一并傳遞過去,這樣后端服務(wù)就不用再進行校驗了。
(1)網(wǎng)關(guān)是唯一的入口,所以微服務(wù)之間的請求就不需要再進行認(rèn)證。
(2)有些請求是不需要進行認(rèn)證的,所以我們加入了白名單進行處理。
(3)jwt的認(rèn)證過程主要是加密,而加密會耗費CPU的運算資源。如果請求量過大,可以將token緩存起來,這樣可以提高網(wǎng)關(guān)服務(wù)器CPU的性能。
(6)身份認(rèn)證過濾器實現(xiàn)
對于認(rèn)證過濾器實現(xiàn)類GlobalFilter和Ordered接口
1.GlobalFilter是gateway中的一個全局過濾器
2.我們知道gateway中的核心由一個過濾器鏈組成,這個過濾器鏈中的一個個過濾器是由Ordered進行排序的,數(shù)值越小越靠前執(zhí)行。
3.ServerWebExchange是gateway中的一個網(wǎng)絡(luò)交換器,它的內(nèi)部封裝了HTTP請求信息和響應(yīng)信息,我們可以在Filter中根據(jù)這個ServerWebExchange對請求信息或者響應(yīng)信息進行攔截,然后進行響應(yīng)的操作。
4.consumer是Java8提供了一個消費性函數(shù)式接口,對此我們可以通過lambda快速向請求頭中加入解析后的用戶信息
5.一般情況下,請求和響應(yīng)中的信息是不能修改的,但gateway為我們提供類一個mutate方法,專門用來修改請求和響應(yīng)信息。由于我們通過ServerWebExchange進行數(shù)據(jù)交換的,所以我們可以先將信息追加到ServerHttpRequest中,然后再將ServerHttpRequest封裝到ServerWebExchange中。
總結(jié)
以上是生活随笔為你收集整理的GitHub轻松阅读微服务实战项目流程详解【第二天:API网关的设计与实现】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GitHub轻松阅读微服务实战项目流程详
- 下一篇: GitHub轻松阅读微服务实战项目流程详