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中。

/*** 身份认证过滤器* @author: Ronin* @since: 2021/10/5* @email:* 统一认证的实现方式是自定义实现全局过滤器,在过滤器里面可以处理白名单放行、认证校验、动态处理请求参数等*/
@Component
public class AuthFilter implements GlobalFilter, Ordered {@Autowired  //白名单配置类private SystemPropertiesConfig systemPropertiesConfig;@Override   public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 白名单Path,获取白名单,获取配置文件中的白名单Set<String> whiteList = this.getWhiteList();//获取请求信息中的请求路径String path = exchange.getRequest().getPath().toString();// 主页接口、图书接口正则匹配,如果匹配这两个表示不用登录就可以访问boolean indexMatch = Pattern.matches("/index[^\\s]*", path);boolean bookMatch = Pattern.matches("/book/[^\\s]*", path);// 白名单接口、开放接口放行if (whiteList.contains(path) || bookMatch || indexMatch) {return chain.filter(exchange);}String[] segments = path.split("/");if (!whiteList.contains(segments[1])) {// 认证--从请求头中获取token,通过jwt进行校验String token = exchange.getRequest().getHeaders().getFirst("token");Result<User> result = JwtUtil.validationToken(token);if (result.getCode() == HttpCodeEnum.OK.getCode()) {// 认证通过User user = result.getData();// 追加请求头用户信息Consumer<HttpHeaders> httpHeaders = httpHeader -> {httpHeader.set("userId",user.getId().toString());httpHeader.set("nickName",user.getNickName());};ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate().headers(httpHeaders).build();exchange.mutate().request(serverHttpRequest).build();return chain.filter(exchange);}// 认证过期、失败,均返回401ServerHttpResponse response = exchange.getResponse();//将对象转换为byte  - json字符串byte[] bits = JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory().wrap(bits);response.setStatusCode(HttpStatus.UNAUTHORIZED);// 指定编码,否则在浏览器中会中文乱码response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");return response.writeWith(Mono.just(buffer));}return chain.filter(exchange);}@Overridepublic int getOrder() {return 0;  //数值越小,该过滤器越向前执行}/*** 请求白名单* @return*/private Set<String> getWhiteList(){String whitelists = this.systemPropertiesConfig.getWhitelist();if (StringUtils.isEmpty(whitelists)) {return new HashSet<>();}Set<String> whiteList = new HashSet<>();String[] whiteArray = whitelists.split(",");for (int i = 0; i < whiteArray.length; i++) {whiteList.add(whiteArray[i]);}return whiteList;}
}

GitHub轻松阅读微服务实战项目流程详解【第二天:API网关的设计与实现】相关推荐

  1. GitHub轻松阅读微服务实战项目流程详解【第一天:数据库表设计及其环境搭建、项目运行】

    One Day 1.数据库表详解 2.项目环境准备 github地址:https://github.com/Zealon159/light-reading-cloud 项目服务端主要使用SpringB ...

  2. GitHub轻松阅读微服务实战项目流程详解【第四天:账户服务的设计与实现】

    Four Day 1.配置文件精解 (1)boootstrap.yml (2)配置中心的yml文件 2.Config (1)书架线程池配置 (2)Mybatis及其Swagger配置 (3)Redis ...

  3. GitHub轻松阅读微服务实战项目流程详解【第三天:公共模块的设计与实现】

    Three Day 1.缓存 (1)账户中心缓存Key (2)图书资源缓存Key (3)精品页缓存key (5)缓存操作类 2.常量 (1)精品页常量类 (2)jwt常量类 3.图书相关枚举 (1)图 ...

  4. go设置后端启动_名企实习项目|后端开发岗go微服务实战项目启动,大牛导师带你拿offer!...

    「DAC实习项目早知道」 今天是第2期实习项目推送 --go微服务实战项目-- 岗位职责 Position Description 1.负责协助高质量的设计和编码: 2.主要语言为Golang: 3. ...

  5. go设置后端启动_名企实习项目 | 后端开发岗go微服务实战项目启动,大牛导师带你拿offer!...

    「DAC实习项目早知道」 今天是第2期实习项目推送 --go微服务实战项目-- 微服务是近年来非常流行的架构,是后端开发工程师必备技能. 什么是微服务? 微服务(Microservices Archi ...

  6. 【最新最全】Java微服务实战项目【尚医疗】_智慧医疗管理项目_基于若依框架快速开发

    尚医疗是专门为各大医院.门诊提供的一款医疗管理平台.系统包含:系统管理.药品进销存管理.看病就诊.收费管理.检查管理.数据统计等核心模块.通过尚医疗系统可以快速.方便的管理病人从挂号到门诊结束所涉及到 ...

  7. Java微服务实战项目推荐

    以下是我推荐的几个Java微服务实战项目: Spring Cloud微服务电商项目:这是一个完整的电商应用程序,使用Spring Cloud实现微服务架构.它包括注册中心.配置中心.网关.商品服务.订 ...

  8. APP开发项目流程详解,长知识了!

    APP的开发流程并不复杂,APP开发人员一般都包含着UI设计师 .前端开发.后端开发.测试专员.产品经理等等. 而根据开发人员的分工不同,可以把APP的开发项目流程分为三个阶段:需求阶段–开发阶段–发 ...

  9. 微服务实战项目-学成在线-课程发布模块

    学成在线-课程发布模块 1 模块需求分析 1.1 模块介绍 课程信息编辑完毕即可发布课程,发布课程相当于一个确认操作,课程发布后学习者在网站可以搜索到课程,然后查看课程的详细信息,进一步选课.支付.在 ...

最新文章

  1. 华为手机媒体音量自动静音_华为手机的音量键还可以这么用,涨见识!
  2. 干货丨一文介绍机器学习中基本的数学符号
  3. 马云“赢在中国”对于80后创业者的忠告
  4. LeetCode Additive Number(递归)
  5. 印象笔记电脑版使用技巧_印象笔记使用攻略
  6. php mysql 非空_MySQL非空约束(NOT NULL)
  7. Android 中的接口回调
  8. Go在谷歌:以软件工程为目的的语言设计
  9. Apache Zookeeper入门1
  10. 执行NET 命令无法使用超过20个字符的组名或用户名
  11. Microsoft Visual Studio Installer Project模板下载太慢解决办法
  12. c++ opencv [ INFO:0] global c:\build\master_winpack-build-win64-vc15\***
  13. java mysql图书馆管理系统源码+论文
  14. 基于ATtiny85制作MIDI数字音乐盒
  15. 深度学习数据增强方法-内含(亮度增强,对比度增强,旋转图图像,翻转图像,仿射变化扩充图像,错切变化扩充图像,HSV数据增强)七种方式进行增强-每种扩充一张实现7倍扩)+ 图像缩放代码-批量
  16. worldwind 三维模型加载优化总结
  17. 绝地求生一直崩溃的异常解决
  18. urllib库(二)parse模块:urlparse()/urlsplit(),parse_qs()/parse_qsl(),urlunparse()/urlunsplit(),urlencode()
  19. 就这样,我走完了程序员的前五年...
  20. 大数据、云计算、物联网、数据仓库、OLAP、OLTP、等大数据你必须知道并且了解的概念及相关关系,我的一些总结

热门文章

  1. 影响一生的职业建议 [转] - 看懂了不一定在高位,在高位的必须看懂了、信息量很大,多学学!...
  2. 壊小子的学习【日常阅读篇】(四)与阅读有关的那些事儿
  3. 需求规格说明书格式及要求
  4. web服务器网站网速慢的原因,apache配置优化 - 解决apache环境下网站访问速度慢的问题...
  5. 拉马车 的游戏 c语言编程,蓝桥杯 拉马车(模拟)
  6. stm32g474教程_STM32-开发入门教程
  7. android 相机纹理,Android平台Camera实时滤镜实现方法探讨(五)--GLSurfaceView实现Camera预览...
  8. url充定向 html转义,html、javascript、url特殊字符的转义诠释及使用方法详解
  9. mac笔记本怎么外接显示屏_苹果MAC笔记本怎么外接显示器?
  10. 计算机一级b考试理论知识,全国计算机等级考试一级b知识点