GitHub轻松阅读微服务实战项目流程详解【第二天:API网关的设计与实现】
Two Day
- 1.配置文件精解
- (1)bootstrap.yml文件
- (2)nacos中關于gateway的配置信息
- (3)applicaton.properties白名單配置
- 2.代碼詳解
- (1)IP限流
- (2)白名單
- (3)Jwt工具類驗證token的有效性
- (4)網關層面快速失敗返回接口
- (5)微服務安全認證流程
- (6)身份認證過濾器實現
github地址:https://github.com/Zealon159/light-reading-cloud
該網關層面使用Spring GateWay進行實現。
1.配置文件精解
(1)bootstrap.yml文件
spring:application:# 服務邏輯名稱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中關于gateway的配置信息
server:port: 8010spring:application:# 服務邏輯名稱name: light-reading-cloud-gatewaycloud:gateway:discovery:locator:enabled: true #開啟gateway的注冊和發現lowerCaseServiceId: true #將請求路徑中的服務名小寫,因為服務注冊時,Nacos將其轉換成大寫了routes: #路由匹配- id: book-center-rpc uri: lb://light-reading-cloud-book #服務地址predicates: #斷言,匹配路徑和請求方式- Path=/book/**- Method=GETfilters:# 降級配置- name: Hystrixargs:name: fallbackcmdfallbackUri: forward:/fallback #失敗了直接跳轉到該路據,這個接口是用戶失敗后快速返回的# 限流配置- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 3 # 每秒允許處理的請求數量redis-rate-limiter.burstCapacity: 5 # 每秒最大處理的請求數量key-resolver: "#{@ipKeyResolver}" # 限流策略,對應策略的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 #并發執行的最大線程數,默認10maxQueueSize: 1000 #BlockingQueue的最大隊列數,默認值-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表達式或者匿名函數都可以快速實現* @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比較適用于微服務的安全認證,JWT是一種安全認證規范,token中存儲了用戶信息,只有在服務端才能根據密鑰進行解密。
public class JwtUtil {/*** 身份認證* @param jwt 令牌* @return 成功狀態返回200,其它均為失敗*/public static Result<User> validationToken(String jwt) {try {//解析JWT字符串中的數據,并進行最基礎的驗證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) {// 系統錯誤return ResultUtil.unAuthorized();}}}(4)網關層面快速失敗返回接口
public class FallbackController {@GetMapping("/fallback")public Result fallback() {return ResultUtil.fail();} }(5)微服務安全認證流程
常用的認證方式主要有三種:Session、HTTP Basic Authentication 和 Token。
- session 是認證中最常用的一種方式,也是最簡單的。用戶登錄后將信息存儲在后端,客戶端則通過 Cookie 中的 SessionId 來標識對應的用戶。
- HTTP Basic Authentication 也就是 HTTP 基本認證,它是 HTTP 1.0 提出的一種認證機制。HTTP 基本認證的原理是客戶端在請求時會在請求頭中增加 Authorization,Authorization 是用戶名和密碼用 Base64 加密后的內容。服務端獲取 Authorization Header 中的用戶名與密碼進行驗證。
- Token 中會存儲用戶的信息,然后通過加密算法進行加密,只有服務端才能解密,服務端拿到 Token 后進行解密獲取用戶信息。
Token更適用于微服務的安全認證,本項目采用了token這種認證方式,并基于JWT的安全認證規范。
jwt是一種認證規范,它允許我們通過jwt在用戶和服務器之間傳遞可靠的信息。在通信過程中進行身份認證
Ⅰ.用戶進行登錄時,將用戶名和密碼提交給認證服務器,服務器會驗證用戶提交信息的合法性,如果驗證成功,則會返回一個token,客戶端將token保存起來
Ⅱ.用戶再次請求服務器時,一般會將token放到請求頭中。當請求達到網關后,會在網關中對token進行校驗;如果校驗成功,網關會將其轉發到后端服務中,轉發時會將用戶信息一并傳遞過去,這樣后端服務就不用再進行校驗了。
(1)網關是唯一的入口,所以微服務之間的請求就不需要再進行認證。
(2)有些請求是不需要進行認證的,所以我們加入了白名單進行處理。
(3)jwt的認證過程主要是加密,而加密會耗費CPU的運算資源。如果請求量過大,可以將token緩存起來,這樣可以提高網關服務器CPU的性能。
(6)身份認證過濾器實現
對于認證過濾器實現類GlobalFilter和Ordered接口
1.GlobalFilter是gateway中的一個全局過濾器
2.我們知道gateway中的核心由一個過濾器鏈組成,這個過濾器鏈中的一個個過濾器是由Ordered進行排序的,數值越小越靠前執行。
3.ServerWebExchange是gateway中的一個網絡交換器,它的內部封裝了HTTP請求信息和響應信息,我們可以在Filter中根據這個ServerWebExchange對請求信息或者響應信息進行攔截,然后進行響應的操作。
4.consumer是Java8提供了一個消費性函數式接口,對此我們可以通過lambda快速向請求頭中加入解析后的用戶信息
5.一般情況下,請求和響應中的信息是不能修改的,但gateway為我們提供類一個mutate方法,專門用來修改請求和響應信息。由于我們通過ServerWebExchange進行數據交換的,所以我們可以先將信息追加到ServerHttpRequest中,然后再將ServerHttpRequest封裝到ServerWebExchange中。
總結
以上是生活随笔為你收集整理的GitHub轻松阅读微服务实战项目流程详解【第二天:API网关的设计与实现】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GitHub轻松阅读微服务实战项目流程详
- 下一篇: GitHub轻松阅读微服务实战项目流程详