API网关系统架构

  1. 云栖社区>
  2. 博客>
  3. 正文

API网关系统架构

小飞哥1112 2018-04-22 16:04:43 浏览6338
展开阅读全文


这是系统架构的第二篇。目的嘛:一来帮助自己理清网关架构,二来将自己觉得好的架构分享出来给大家。

本文主要讨论:

API网关业务域:统一接入、安全防护、流量管控、协议转换

API网关核心指标:安全、高可用、高并发、方便扩展、方便运维

API网关架构:系统领域划分、防护层、接入层、核心层架构。

API网关的设备安全解决方案。

一 API网关业务域

API网关作为内外的桥梁;对外通过暴露HTTP接口提供服务;对内管理所有业务系统对外暴露的接口,并将请求分发到内部各个业务系统。

1  业务域

cf4d216b271c400d2fae450a4e57a380ff2da8c4

2  统一接入

作为对外的门面,网关应该拥有统一且简洁的规范,以减少接入的成本。同时这也可以体现出专业化的技术能力。

统一的规范应该至少包括以下内容:

统一的编码规则。

统一的返回数据的结构。

统一的错误申明与处理方式。

统一的公共参数,例如识别用户身份的token,识别渠道来源的source等。

统一的加签、加解密方式;统一的身份认证或安全体系。

3  安全防护

作为请求的入口,是保护内部系统的第一道屏障,当遭受攻击时要尽可能的将影响降为最低。所以应该具备清洗恶意攻击的流量,能够在流量异常的时候屏蔽这些异常请求,或者对这些请求进行限制。

验证请求信息,屏蔽非法请求,确保接口的安全性,保证所有达底层业务系统的请求都是安全、可靠地。

常用的手段有:

防篡改,例如参数加签。

请求安全:请求端加密,网关层解密。

身份校验:必须是合法的用户,必须是合法的第三方。

接口安全级别。例如:接口不需要登录即可访问;需要登录方可访问;接口仅提供给app,H5不能使用等

接口权限限制。

黑白名单。

HTTPS

 

4  流量管控

系统的承受能力都有限,例如:当营销活动做得好时,系统请求量超过系统的服务能力的极限,如果放任不管,势必压垮内部系统,此时应该对内部系统提供一定的保护。

作为服务能力的出口,一旦不可用,在外部看来所有的服务都不可用,所以应该网关必须高可用、高并发。

常见的手段有:限流、降级、熔断

5  协议转换

对外提供的都是HTTP接口,但内部系统是使用Dubbo来相互调用的,所以网关势必要能够完成协议转换,并通过负载均衡等手段将请求高效的分发到内部系统中去。

6  其他业务

1)   接口文档管理

业务发展变化势必引起服务的增加或者扩展,如果能够统一的对文档进行维护,势必会降低开发、联调、定位问题成本。我们的做法是通过api规范自动生成接口文档。

2)   调试工具和示例

当接入方很多,提供一个调试工具或者提供示例将会极大的简化接入成本。

3)   SDK自动生成能力

为客户端(Android、IOS或者第三方调用者)生成SDK,简化接入、降低对方开发成本。

4)   API增强

参数注入。例如注入userId、来源、ip等。 

合并多个请求。例如:在一个页面中可能需要访问多个接口才能拿到所有的数据,此时为了方便调用方使用,网关可以提供合并多个接口的能力,让调用方同时发起多个http请求。

 API网关核心指标

1  模型

22aa0e75adf228fa40f39360e5f3280678c03988

2  安全性

内容见“安全防护”部分。

3  高并发性

作为企业级API的入口,所有接口都通过网关,流量可想而知是非常大的。

常见的手段有:

多级缓存

应用级缓存:堆缓存、磁盘缓存;

分布式缓存:热点数据缓存

并发:线程池;请求缓存;请求合并

4  高可用性

网关故障时,在外部来看就是整个系统不可用;所以网关应该做到7*24小时稳定运行;能够自动伸缩;API热更新;对做到接口级别、应用级别的限流和降级;支持负载均衡;支持多机房;(准)实时的系统监控;应该有一定的隔离性,避免单点故障引起雪崩。

5  扩展性性

网关纵向扩展性:企业的服务能力、安全性随业务的发展而变化,所以网关要能随着业务发展灵活的调整。

网关横向扩展性:网关需要能应对业务发展而带来的流量激增,至少紧急是可以通过增加机器带来成比例的增加服务能力。

网关应该避免频繁调整。

6  运维成本

升级发布网关、新服务的接入应该简单,方便。

 

 API网关架构

1  几个要点

要支持高并发、高可用。

不必要、非安全的请求不要到下游服务中去。

网关不负责任何业务相关内容,仅负责协议转换、请求转发。

接口要符合规范;文档与接口应同步。

2  网关整体模块

8c975b732c81d4a58eccb281cac9fdc56a75bec8

 

3  系统领域划分

5fedac5d3bdef57890a38a9e449b82008132ee15

防护层

负责安全与流控;保障系统安全;可以直接在nginx层编码,例如openresty。

接入层

负责统一接入相关的所有内容。

核心层

负责请求验证、API增强、协议转换、负载均衡等。另外核心层也可以包含限流、降级、熔断功能。

4  系统分层模型

39cb6ae0517e0795a063780738fdbbdc75111c11

服务提供者将服务注册到网关

防护层作为网关的第一入口;过滤掉非法、无法处理的请求后,将请求交给核心层处理。

核心层转换协议通过Dubbo调用服务提供者接口,然后将调用数据沉淀,为防护层限流、降级、熔断等提供数据支撑。

 

5  防护层

防护层主要业务域是:限流、降级、熔断;核心目标是保证后端系统不会大流量、异常流量击垮。

防护层是入口,从性能上考虑,完全可以通过在nginx层实现,例如通过openresty实现。架构如下:

623d6a2c4c3c12195f266edf1b826723f961c619

 

6  接入层

作为统一接入方,网关应该提供API规范,以保证对API的统一性。

1)   接入规范

a)    模型

874f993bd76bda9ca08c5a3af947ab3e778c6226

b)    规范

API

用于对api进行归类,限制错误码范围等。

API方法

对应于每一个API接口,包括:名称、描述、使用范围、安全级别、状态、适用范围。

公共参数

例如:token、sign、渠道、format、方法、应用等。

业务参数

名称、是否必填、默认值、是否加密等

错误码声明

类、属性注释

 

2)   接入

服务提供者,根据规范定义接口,然后接入到网关,网关进行校验,校验通过则生成文档、SDK、RPC实例等。

07b32e57560d98416c03bd9470799b1381f815c4

3)   文档

通过注解来定义规范,其中非常重要第一点就是生成客户端调用文档,并且文档应该和接入的接口同步更新。因为接入时解析注解,所以很容易做到这一点。

 

 

7  核心层

1)   验证层

验证层主要保证交付给业务系统的接口都是合法、有效的。

安全验证分为:常规型(sign验证)、应用型(Appkey)、用户型(token)、接口型(安全级别、参数必填、非空等)四种验证;这四种分别对应不同层次,用于不同目的。

 

2)   增强层

增强层主要提供API增强功能,例如:支持合并多个api请求;请求参数注入等。

3)   协议转换

将外部的HTTP接口转换成内部的Dubbo接口。

8        高并发、高可用

高并发、高可用技术以后找机会详细分析,这里暂不详细讨论。

从上面的领域划分、系统分层中可以看到,每一层都是可以分布式集群部署,并且可以水平扩展的,最不济的情况是流量激增的时候等比例的增加服务器。

 

 安全

目前有很多的成熟的安全策略,他们足以应对绝大多数公司的安全需要;使用他们的时候需要清晰每种策略的用途以及适用范围。在这里主要介绍常用的几种策略,如:通用安全策略、设备级安全、应用级安全、接口级安全、用户级别安全来介绍几种。

1  核心要素

衡量一个系统是否安全主要有两个核心要素:

破解的难度。

破解后危害范围有多大。

对于开发者而言,通过抓包获取请求的参数,通过分析javascript的逻辑或者反编译app来分析app的逻辑,两方面结合起来就可以伪造用户请求,面对这种困境,我们应该尽可能增大破解难度,降低破解后对系统的危害以及影响面。

2  安全策略

1)   安全策略

8043e45d836ee6c217e9f030b7843763eb933569

2)   通用安全策略

a)    请求信息加签

请求参数加签的最重要目的是实现请求数据防篡改功能。主要用于防止通过修改请求数据伪造请求,攻击系统、破坏用户数据的行为。

一般而言在H5、app中,加签逻辑都可以通过(反编译代码)分析代码来获悉,一般仅仅将加签作为请求防篡改的手段。

如果是服务端A向服务端B发送请求,因为服务端代码部署在内网,他人无法获知其中逻辑,此时可以通过两端约定一个字符串,加签的时候使用此字符串,但是请求时不传递次字符串,服务端B收到请求以后,同样在加签的时候使用此字符串,由此可以实现请求防篡改、请求参数安全的目的。个人并不是很赞同这种做法,主要原因是将请求参数防篡改和请求参数安全两者混淆了,并且因为两端约定的字符串恒定不变,一旦被人破译出此字符串,将导致他人可以完全伪造此参数。

b)    防止请求重复提交

相同的请求多次提交到服务端,在大多数场景中(并不是所有场景中)都不是正常的行为,此时应该处理掉这些重复的请求。常见的处理手段有:客户端提交一次请求以后禁用按钮;客户端进入页面时在页面中保存一个随机字符串,服务端同时受到的请求中含有相同的此值时,忽略后一个请求;服务端防并发处理等等。

c)    注入攻击

最常见的就是SQL注入了。

d)    Cookie劫持

第三方通过javascript获取、修改Cookie的信息。服务端通过httponly模式来设置cookie可以解决这个问题。

e)    混淆打包

混淆打包主要针对app、javascript,用于增大他人破解难度。

3)   设备级安全

设备级安全主要是用于防止第三方通过反编译app、分析javascript代码,解析出系统安全规则,从而完成系统攻击的目的。

后文将介绍一种保障App的设备级安全的方案。

 

4)   应用级安全

常见的场景有:营销活动中,一个用户只能参加一次活动,如一个用户只能秒杀一个商品;同一个ip最多能只能参加10次抽奖。使用验证码接收器,通过虚拟号注册app,刷奖励;同一个ip(某一个时间段内)的请求量不能超过N,防止并发攻击;等等。

这些场景与具体的业务相关,而且很多时候规则也会各有不同,通常使用分布式锁、风控等手段一起这些问题。

 

5)   接口级安全

常见的场景有:接口的参数、返回结果是否需要加密;接口有只有在登录状态时才能访问还是任何时候都能访问;接口是否只是针对app的还是app、h5、web都可以访问;请求中是否包含了接口要求的所有参数;参数格式是否符合要求等等。

 

6)   用户级别安全

常见的场景有:是否拥有某一个菜单的权限;是否必须登录或授权才能使用某部分功能;是否允许自己的信息被他人查看;等等。

 

3  企业级设备安全解决方案

没有最好的方案,只有最适合的方案。设计安全方案时要充分考虑公司的安全级别、业务诉求、开发人员水平、使用复杂度等。

以下是之前使用过的一种安全解决方案。这里仅讨论RSA加密的方式,其实也支持AES加密,流程比较简单,所以就不做讨论。

1)   设备注册

b795a29e0be5095b806fb82b43b681eb11760a1e

app第一次打开的时候进行设备注册,其核心目标是为了生成device token和证书。

device token是设备token,通过它可以解析出是哪一台设备。

证书中包含RSA加密的公钥,如果请求参数需要加密,客户端可以通过此公钥进行加密。

2)   用户登录

258aa04c0818fa606a48e2b2bed1f9802c9bf278

登录流程其实是获取user token的过程;这样做的目的是:这里还将用户信息和设备信息绑定在一起了,可以做到一台设备一个用户;可以很简单的实现设备互踢,即一个用户只能在一个设备互踢。

3)   HTTP请求处理

a9731da2020ff856323b24d55d94571fc0ade80e

收到HTTP请求以后,通过解析user token或者device token来获取用户、设备信息,如果是合法的用户、设备,那么允许用户的后续操作,如果是不合法的,将请求直接拦截掉。

4)   总结

a)    流程

在app第一次打开时进行设备注册流程,同时下发device token、RSA公钥;除非device token失效,否则不重新注册设备。

客户端请求时通过RSA公钥加签,如果参数需要加密也通过此公钥加密。

服务端收到请求以后先通过解析device token(如果已登录则解析user token),如果出错直接返回,否则进行下一步。

服务端通过RSA私钥对请求数据进行验签,如果失败直接返回;如果成果则进行下一步。

进行协议转换,将HTTP请求转换为Dubbo请求,调用业务系统的接口。

返回结果。

b)    安全性分析

如果想要通过分析代码、抓取请求破解此流程,则必须按照整套流程进行。因为APP进行了混淆打包,所以此过程难度较大。

如果用户密码泄露,在用户重新登录之前,此用户的数据存在风险,但其他用户不会受到影响。

用户在另外设备上登录以后,之前的登录状态时效,即当用户手机丢失时,只需要找一台设备登陆一次即可保证自己的信息安全。

 

4  AES、RSA混合加密的安全方案

参考博客《AES+RSA混合加密原理详解》

https://blog.csdn.net/u011339364/article/details/78120904

 

 

 

 

网友评论

登录后评论
0/500
评论
小飞哥1112
+ 关注