我们使用网关来做这些事情:1.实现路由功能;2.集成SwaggerAPI文档;3.全局修改文件URI;4、统一验证Token;5.资源访问权限统一校验;6、对外开放的API统一签名校验。实现路由功能实现路由功能的目的是为了统一流量入口,为前端屏蔽后端多个微服务的存在,不需要为每个微服务通过域名暴露接口对外网后端的微服务。我们之前的项目使用nginx来实现请求路由功能,但是我们需要的不仅仅是路由功能,路由功能只是网关最基本的功能。将SwaggerAPI文档项目集成到微服务中后,接口文档也比较分散。前期我们使用nginx做路由,配置swagger路由太麻烦。前端同事也需要记住路由规则,所以我们放弃了通过配置路由文档来访问接口。在没有网关之前,前端同事无法访问测试环境的接口文档。我们只能在本地启动微服务,让前端同事通过局域网访问API接口文档。引入网关后,我们希望统一API文档入口。详细的集成步骤笔者单独整理了教程《在网关实现合并多个微服务Swagger接口文档的详细步骤》,最终效果如下图所示。全局修改文件URI由于可能修改域名和路由前缀,一般图片上传后,我们只将图片的相对路径存储到数据库,但是给前端的响应必须是完整的URL,否则图片无法访问,所以必须拼接所有图片url的域名和路由才可以响应。以修改用户头像为例,前端需要先调用文件上传接口上传图片并获取图片上传后的url,然后用图片url调用修改用户头像的接口.由于前端可能需要实现上传后的回显,所以文件上传接口响应的图片url也必须完整,导致前端调用修改用户头像接口传递图片url也是完整的,我们要实现修改用户头像的接口去掉头像url的域名和路由。一个接口可以这样,那么多个接口呢?如果不怕麻烦的话,确实每个接口都可以这么写。对于这样重复的操作,我们选择将它们移到网关统一实现,其他微服务在修改路由和域名后不需要做任何改动。图片url的域名和路由去除或拼接并不难。难点在于如何从请求体和响应体中识别出哪些字段是文件url。首先是如何从请求正文中识别哪个字段是文件URL。由于前端上传的文件url是完整的,可以根据域名、路由、文件名后缀进行正则匹配替换。域名、路由、文件名后缀三个条件缺一不可。匹配域名和路由是为了避免将图片链接匹配到第三方网站或以前上传的图片(向后兼容),匹配文件名后缀是为了保证这是一个文件链接,而不是接口链接。二是如何从响应体中识别哪个字段是文件链接。我们只能通过后缀名来匹配。匹配完后缀名后,我们需要判断这个链接是否已经是一个完整的链接。对于完整的链接,不需要拼接。实现中需要注意的事项:当我们修改请求或响应体时,它的长度可能会发生变化,所以一定要记得修改请求或响应头的ContentLength。如果是基于SpringCloudGateway实现的网关,由于是异步响应,对于请求包,先将请求头写入InputStream流,再写入body,而不是一起写,所以当我们修改body时,我们修改请求的ContentLengthheader是没有意义的。如果修改后的body长度无法预知,解决方法可以是去掉请求头的ContentLength,换成Transfer-Encoding:chunked。统一验证token有效性当仍然使用nginx做请求转发时,每个微服务都需要写一套token验证逻辑,比如通过拦截器验证请求是否携带token,token是否有效。获取用户信息需要先从请求头中获取token,然后通过redis查询获取用户身份信息。引入网关后,我们只需要对网关进行token验证即可。验证通过后,从redis中获取用户信息,写入请求头,并从请求头中去除Token。userId由网关传递给后台微服务,后台微服务不需要再次根据Token获取用户ID。资源访问权限的统一校验引入网关后,除了登录(Token)校验外,用户访问资源的校验都可以在网关中实现,各个微服务不再关心权限校验的问题。具体的用户资源访问权限验证仍然由用户中心完成,网关只负责调用用户中心提供的权限验证接口完成用户资源访问权限验证。这可能会影响接口的性能。实现权限验证接口时尽量让用户中心读取并缓存所有数据源。对外开放的API统一签名验证我们对外开放的API采用基于签名的机制来实现身份认证,可以控制签名的时限。作者之前写过一篇关于签名机制的文章:《一种基于签名算法且简单安全的API授权机制》。在引入网关之前,我们是通过AOP实现的,只需要在开放的API方法上加注解即可。密钥、私钥和签名有效期在配置文件中配置。引入网关后,可以在网关上统一实现签名校验。如果API需要被多个不同的主体使用,即会有多个合作的客户系统,那么key和key必须在后台提供配置功能,并将配置持久化到数据库中。网关还需要支持基于密钥查询密钥,然后验证签名。网关可以在内存中缓存密钥和密钥字典,并定期刷新。或者缓存到redis,当某个账户的key更新时同步刷新缓存。总结网关一般用于统一流量入口、统一认证和流量控制。此外,一些与业务无关的重复性操作也可以在网关中实现。比如本文介绍的统一SwaggerAPI文档入口就是文件url自动去除或拼接域名和路由。对内对外提供的接口也可以通过网关进行签名验证和访问频率限制。本文转载自微信?「爪哇艺术」,可通过以下二维码关注。转载本文请联系爪哇艺术公众号。
