架构问题分析
API网关有很多实现方式,我们通过SpringCloud Gateway实现
使用Nacos作为配置中心
1.3 API网关
1.3.1 搭建网关
gateway
需求:创建新的网关模块gateway并配置路由
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- 监控检查--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- nacos配置中心依赖支持 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> -->
跨域问题配置类
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsWebFilter; import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; import org.springframework.web.util.pattern.PathPatternParser; /** * 跨域支持 */ @Configuration public class CorsConfig { @Bean public CorsWebFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedMethod("*"); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); source.registerCorsConfiguration("/**", config); return new CorsWebFilter(source); } }
配置文件 案例
server: port: 8888 spring: application: name: tanhua-gateway cloud: nacos: discovery: server-addr: 192.168.136.160:8848 gateway: globalcors: add-to-simple-url-handler-mapping: true corsConfigurations: '[/**]': allowedHeaders: "*" allowedOrigins: "*" allowedMethods: - GET - POST - DELETE - PUT - OPTION routes: # 手机端访问 /app/login /login - id: tanhua-app-server uri: lb://tanhua-app-server predicates: - Path=/app/** filters: - StripPrefix= 1 # 管理后台 - id: tanhua-admin uri: lb://tanhua-admin predicates: - Path=/admin/** filters: - StripPrefix= 1 #自定义配置,定义不需要校验token的连接 gateway: excludedUrls: /user/login,/user/loginVerification,/system/users/verification,/system/users/login
1.3.2 配置鉴权管理器
在网关内部可以通过过滤器完成统一鉴权,限流,日志记录等操作。
gateway
配置鉴权过滤器
@Component public class AuthFilter implements GlobalFilter, Ordered { @Value("${gateway.excludedUrls}") private List<String> excludedUrls; //配置不校验的连接 @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //获取当前请求连接 String url = exchange.getRequest().getURI().getPath(); System.out.println( "url:"+ url); //放行不需要校验的接口 if(excludedUrls.contains(url)){ return chain.filter(exchange); } //获取请求头中的token String token = exchange.getRequest().getHeaders().getFirst("Authorization"); //后台系统页面发送的token以"Bearer "开头,需要处理 if(!StringUtils.isEmpty(token)){ token = token.replace("Bearer ", ""); } ServerHttpResponse response = exchange.getResponse(); //使用工具类,判断token是否有效 boolean verifyToken = JwtUtils.verifyToken(token); //如果token失效,返回状态码401,拦截 if(!verifyToken) { Map<String, Object> responseData = new HashMap<>(); responseData.put("errCode", 401); responseData.put("errMessage", "用户未登录"); return responseError(response,responseData); } return chain.filter(exchange); } //响应错误数据 private Mono<Void> responseError(ServerHttpResponse response,Map<String, Object> responseData){ // 将信息转换为 JSON ObjectMapper objectMapper = new ObjectMapper(); byte[] data = new byte[0]; try { data = objectMapper.writeValueAsBytes(responseData); } catch (JsonProcessingException e) { e.printStackTrace(); } // 输出错误信息到页面 DataBuffer buffer = response.bufferFactory().wrap(data); response.setStatusCode(HttpStatus.UNAUTHORIZED); response.getHeaders().add("Content-Type", "application/json;charset=UTF-8"); return response.writeWith(Mono.just(buffer)); } /** * 设置过滤器的执行顺序 */ @Override public int getOrder() { return Ordered.LOWEST_PRECEDENCE; } }
1.4 Nacos配置中心
Nacos提供了注册中心和配置管理的能力,使用Nacos可以快速实现服务发现、服务配置管理等需求。
这里以网关工程(<font color=red><b>tanhua-gateway
</b></font>)为例
1.4.1 添加依赖
tanhua-gateway
-
添加配置中心依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
添加引导文件bootstrap.yml,并设置
server: port: 8888 spring: profiles: active: prod application: name: tanhua-gateway cloud: nacos: discovery: server-addr: 192.168.136.160:8848 config: server-addr: 192.168.136.160:8848 file-extension: yml
1.4.2 nacos添加配置
在nacos中添加网关配置
添加配置内容
配置如下内容
server: port: 8888 spring: cloud: gateway: globalcors: add-to-simple-url-handler-mapping: true corsConfigurations: '[/**]': allowedHeaders: "*" allowedOrigins: "*" allowedMethods: - GET - POST - DELETE - PUT - OPTION routes: # 用户微服务 - id: tanhua-app-server uri: lb://tanhua-app-server predicates: - Path=/app/** filters: - StripPrefix= 1 # 文章微服务 - id: tanhua-admin uri: lb://tanhua-admin predicates: - Path=/admin/** filters: - StripPrefix= 1 gateway: excludedUrls: /user/login,/user/loginVerification,/system/users/verification,/system/users/login
项目架构总结
-
加入网关与配置中心
-
通过统一过滤器完成统一鉴权
-
获取请求头中的token
-
通过工具类判断token是否失效
-
如果失效则返回状态码401,否则放行
-
-
nacos配置中心