简介
在 SpringCloud 中网关作为一个重要的组成部分,网关的角色是作为一个 API 架构,用来爱护、加强和管制对于 API 服务的拜访。
API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的零碎,用来治理受权、访问控制和流量限度等,这样 REST API 接口服务就被 API 网关爱护起来,对所有的调用者通明。因而,暗藏在 API 网关前面的业务零碎就能够专一于创立和治理服务,而不必去解决这些策略性的基础设施。
所谓的 APIl 网关,就是指零碎的对立入口,它封装了应用程序的内部结构,为客户端提供对立服务,一些与业务自身性能无关的公共逻辑能够在这里实现,诸如认证、鉴权、监控、路由转发等等。
引出问题
1. 客户端须要保护服务端的各个地址代码艰难
2. 认证鉴权简单
3. 跨域问题
咱们开始吧
咱们间接新建一个模块命名 api-getaway
具体目录如下:
gateway 具体是 yml 的配置
server:
port: 7000
spring:
application:
name: api-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848 #注册到 nacoos
gateway:
discovery:
locator:
enabled: true #让 gateway 能够发现 nacos 中的微服务
routes: #路由数组能够放多个路由。满足什么条件转发到哪个微服务上
- id: product_route #以后路由标识,默认 uuid
uri: http://localhost:8081 #要转发的地址
order: 1 #路由越小优先级越高
predicates: #断言(条件判断,返回值是 bool,满足条件的)能够自定义路由配置详情看 AGEROUTER
- Path=/product-serv/** #当申请的规定满足
filters: #过滤器 自定义过滤器 Log
- StripPrefix=1 #在申请转发门路去掉一层
进行代码测试:咱们间接拜访原来的商品查问接口
是能够间接查问到的
而后咱们拜访咱们的 api 网关
通过地址也是能够查问进去的,这样就是实现了咱们网关的申请转发。
这样会有另一个问题,就是如果咱们频繁的批改接口,那么咱们就须要频繁的批改 yml 文件,有没有主动查找 ip 的呢,其实是有的,就是咱们通过 nacos 中的服务名称进行调用,这里咱们须要在 pom 文件引入 nacos,而后在启动类中增加注册发现注解(在之前章节都有讲述,再次不做赘述)。重要的还是咱们 yml 的配置。
server:
port: 7000
spring:
application:
name: api-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848 #注册到 nacoos
gateway:
discovery:
locator:
enabled: true #让 gateway 能够发现 nacos 中的微服务
routes: #路由数组能够放多个路由。满足什么条件转发到哪个微服务上
- id: product_route #以后路由标识,默认 uuid
#uri: http://localhost:8081 #要转发的地址
uri: lb://service-product #lb 负载平衡 前面是具体微服务的标识
order: 1 #路由越小优先级越高
predicates: #断言(条件判断,返回值是 bool,满足条件的)能够自定义路由配置详情看 AGEROUTER
- Path=/product-serv/** #当申请的规定满足
filters: #过滤器 自定义过滤器 Log
- StripPrefix=1 #在申请转发门路去掉一层
# - Log=ture,false
最终要的就是这一行 uri: lb://service-product,正文曾经很明确了,值得注意的就是前面的微服务名称,要与 nacos 的统一。
上面就是比拟深刻的问题,一些 断言 与过滤 的问题了。
gateway 蕴含很多个断言:
查看地址:https://docs.spring.io/spring…
基于 Datetime 类型的断言工厂
此类型的断言依据工夫做判断,次要有三个:
AfterRoutePredicateFactory:接管一个日期参数,判断申请日期是否晚于指定日期
BeforeRoutePredicateFactory:接管一个日期参数,判断申请日期是否早于指定日期
BetweenRoutePredicateFactory:接管两个日期参数,判断申请日期是否在指定时间段内
java 能够通过 ZonedDateTime.now() 获取日期值
‐ After=2022-02-22T17:42:47.666-07:00[Asia/Shanghai]
基于近程地址的断言工厂
RemoteAddrRoutePredicateFactory:接管一个 IP 地址段,判断申请主机地址是否在地址段中
‐ RemoteAddr=192.168.1.1/24
基于 Cookie 的断言工厂
CookieRoutePredicateFactory:接管两个参数,cookie 名字和一个正则表达式。判断申请 cookie 是否具备给定名称且值与正则表达式匹配。
‐Cookie=chocolate, ch.
基于 Header 的断言工厂
HeaderRoutePredicateFactory:接管两个参数,题目名称和正则表达式。判断申请 Header 是否具备给定名称且值与正则表达式匹配。
‐Header=X‐Request‐Id,\d+
基于 Host 的断言工厂
HostRoutePredicateFactory:接管一个参数,主机名模式。判断申请的 Host 是否满足匹配规定。
‐ Host=**.testhost.org
基于 Method 申请办法的断言工厂
MethodRoutePredicateFactory:接管一个参数,判断申请类型是否跟指定的类型匹配。
‐Method=GET
基于 Path 申请门路的断言工厂
PathRoutePredicateFactory:接管一个参数,判断申请的 URI 局部是否满足门路规定。
‐ Path=/foo/{segment}
基于 Query 申请参数的断言工厂
QueryRoutePredicateFactory:接管两个参数,申请 param 和正则表达式,判断申请参数是否具备给定名称且值与正则表达式匹配。
‐Query=baz, ba.
基于路由权重的断言工厂
WeightRoutePredicateFactory:接管一个[组名, 权重], 而后对于同一个组内的路由依照权重转发,意思就是如果有十个申请,都是到 product/*,依照 1:9 的转发。
routes:
‐id: weight_route1
uri: host1
predicates:
‐ Path=/product/**
‐ Weight=group3, 1
‐id: weight_route2
uri: host2
predicates:
‐ Path=/product/**
‐ Weight= group3, 9
这边以上就是一些断言工厂了。
自定义断言
咱们来设定一个场景: 假如咱们的利用仅仅让 age 在 (min,max) 之间的人来拜访。
routes: #路由数组能够放多个路由。满足什么条件转发到哪个微服务上
- id: product_route #以后路由标识,默认 uuid
#uri: http://localhost:8081 #要转发的地址
uri: lb://service-product #lb 负载平衡 前面是具体微服务的标识
order: 1 #路由越小优先级越高
predicates: #断言(条件判断,返回值是 bool,满足条件的)能够自定义路由配置详情看 AGEROUTER
- Path=/product-serv/** #当申请的规定满足
- Age=18,60 #限度 18 到 60 的人
filters: #过滤器 自定义过滤器 Log
- StripPrefix=1 #在申请转发门路去掉一层
而后新建相干类,这个类须要留神。gateway 自定义;路由断言工厂后面必须 - Age(能够自定义和配置 yml 文件一样)+RoutePredicateFactory 通过年龄自定义断言
年龄咱们输出正确的范畴内是有的,然而输出不在范畴内的就会有谬误的提醒。
过滤器
Spring Cloud Gateway 的 Filter 的生命周期不像 Zuul 的那么丰盛,它只有两个:“pre”和“post”。
PRE:这种过滤器在申请被路由之前调用。咱们可利用这种过滤器实现身份验证、在集群中抉择
申请的微服务、记录调试信息等。
过滤器类型
Spring Cloud Gateway 的 Filter 从作用范畴可分为另外两种 GatewayFilter 与 GlobalFilter。
GatewayFilter:利用到单个路由或者一个分组的路由上。
GlobalFilter:利用到所有的路由上。
部分过滤器
部分过滤器(GatewayFilter),是针对单个路由的过滤器。能够对拜访的 URL 过滤,进行切面解决。在
Spring Cloud Gateway 中通过 GatewayFilter 的模式内置了很多不同类型的部分过滤器。这里简略将
Spring Cloud Gateway 内置的所有过滤器工厂整顿成了一张表格,尽管不是很具体,但能作为速览使
用。如下:
每个过滤器工厂都对应一个实现类,并且这些类的名称必须以 GatewayFilterFactory 结尾,这是 \
Spring Cloud Gateway 的一个约定,例如 AddRequestHeader 对应的实现类为 \
AddRequestHeaderGatewayFilterFactory。对于这些过滤器的应用形式能够参考官网文档 \
全局过滤器
全局过滤器(GlobalFilter)作用于所有路由,Spring Cloud Gateway 定义了 Global Filter 接口,用户
能够自定义实现本人的 Global Filter。通过全局过滤器能够实现对权限的对立校验,安全性验证等功
能,并且全局过滤器也是程序员应用比拟多的过滤器。
Spring Cloud Gateway 外部也是通过一系列的内置全局过滤器对整个路由转发进行解决如下:
对立鉴权
内置的过滤器曾经能够实现大部分的性能,然而对于企业开发的一些业务性能解决,还是须要咱们本人
编写过滤器来实现的,那么咱们一起通过代码的模式自定义一个过滤器,去实现对立的权限校验。
鉴权逻辑
开发中的鉴权逻辑:
当客户端第一次申请服务时,服务端对用户进行信息认证(登录)
认证通过,将用户信息进行加密造成 token,返回给客户端,作为登录凭证
当前每次申请,客户端都携带认证的 token
服务端对 token 进行解密,判断是否无效。
如上图,对于验证用户是否曾经登录鉴权的过程能够在网关层对立测验。测验的规范就是申请中是否携
带 token 凭证以及 token 的正确性。
具体代码实现
这就是网关的根本实现了,如果更加粗疏的应用还是须要依据业务状况进行更改。
前期会在这个我的项目上一直增加,喜爱的请点个 start~
我的项目源码参考一下分支 220217_xgc_gateway
Gitee:https://gitee.com/coderxgc/sp…
GitHub:https://github.com/coderxgc/s…