[TOC]
## 网关模块
网关模块在这个项目里面起到一个统一访问入口的作用。
因为在微服务架构中,有不同的服务,服务之间的访问端口不一样,造成了访问的困难。
网关是对外的,其他内部服务外部系统是无法直接访问到的,需要通过网关。
## Zuul和Spring Gateway
这2个都可以提供一个网关服务,jfun-cloud现在使用都是zuul,后面会升级成Spring Gateway。
## 网关和服务发现
网关重要功能就是转发服务,提供统一入口。
所以服务都接入我们还需要一个服务都注册中心,这里使用了nacos这个注册中心。
## 网关配置服务的转发
比如下面都配置USER-CENTER就是一个用户中心都服务,这个注册在nacos上面了,这里没有使用动态注册,简便的配置了一个服务。
访问网关的api-user就会转发到对应的服务上面
```
zuul:
routes:
user-center:
path: /api-user/**
service-id: USER-CENTER
strip-prefix: true
```
## 服务作为资源中心
前面的权限模块我们说了认证中心。
而微服务里面,我们内部的服务(比如用户服务、订单服务)可以当成一种资源。
那么我们是否可以把每一个服务作为一个资源中心呢?

这种场景下网关起到一个统一入口的作用,每一个服务都是一个独立的资源服务。
## 网关作为资源中心
基于需要通过网关访问内部服务,而内部服务又是资源,那么现在我让网关委以重任,我把“资源中心”做到网关上面,统一管理(比如配置白名单上面的,统一配置)。

这种场景下面,用户访问网关的时候,我们需要做鉴权处理。
jfun-cloud是使用这种方法做的网关服务。
### 网关权限拦截
~~~
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends OAuth2ClientConfig {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.anyRequest().access("@authenticationService.hasPermissions(request,authentication)");
}
}
~~~
~~~
@Override
public boolean hasPermissions(HttpServletRequest authRequest, Authentication authentication) {
log.debug("正在访问的url是:{},method:{}", authRequest.getServletPath(), authRequest.getMethod());
AntPathMatcher antPathMatcher = new AntPathMatcher();
final String uri = authRequest.getRequestURI();
//获取数据库里面的资源信息
String tmp = (String) authentication.getName();
Set<Resource> resourceSet = resourceService.findAll(authentication.getName());
//鉴权
Optional<Resource> desc = resourceSet.stream().filter(new Predicate<Resource>() {
@Override
public boolean test(Resource resource) {
return StringUtils.isNotEmpty(resource.getUrl())
&& antPathMatcher.match(resource.getUrl(), uri)
&& StringUtils.isNotEmpty(resource.getMethod())
&& authRequest.getMethod().toLowerCase().equals(resource.getMethod().toLowerCase());
}
}).peek(resource -> log.info("匹配权限成功:{}", resource.toString())).findFirst();
return desc.isPresent();
}
~~~
## 更进一步,加上鉴权中心
上面做法网关做了鉴权的操作,这个还可以在进行改造,弄一个鉴权中心,主要就是提供一个服务hasPermissions(判断是否有权限)
这样就可以把网关的鉴权独立出来,不耦合太紧。
## 见仁见智
上面说了网关和权限在一起做出现的问题。
实际操作中,可以根据业务需求和场景,选择合适的方案