• API网关系统架构


     什么是API网关

    API网是一个反向路由:屏蔽内部细节,为调用者提供统一入口,接收所有调用者请求,通过路由机制转发到服务实例。
    API网关是一组“过滤器”集合:可以实现一系列与核心业务无关的横切面功能,如安全认证、限流熔断、日志监控。

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

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

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

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

    一 API网关业务域

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

    1  业务域

     

    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  模型

     

    2  安全性

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

    3  高并发性

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

    常见的手段有:

    多级缓存

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

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

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

    4  高可用性

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

    5  扩展性性

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

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

    网关应该避免频繁调整。

    6  运维成本

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

    三 API网关架构

    1  几个要点

    要支持高并发、高可用。

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

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

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

    2  网关整体模块

    3  系统领域划分

    防护层

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

    接入层

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

    核心层

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

    4  系统分层模型

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

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

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

    5  防护层

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

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

    6  接入层

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

    1)   接入规范

    a)    模型

     

    b)    规范

    API组

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

    API方法

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

    公共参数

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

    业务参数

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

    错误码声明

    类、属性注释

    2)   接入

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

     

    3)   文档

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

    7  核心层

    1)   验证层

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

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

    2)   增强层

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

    3)   协议转换

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

    8        高并发、高可用

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

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

    四 安全

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

    1  核心要素

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

    破解的难度。

    破解后危害范围有多大。

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

    2  安全策略

    1)   安全策略

     

    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)   设备注册

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

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

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

    2)   用户登录

     

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

    3)   HTTP请求处理

     

    收到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

  • 相关阅读:
    luogu_1168: 中位数
    luogu_4762: [CERC2014]Virus synthesis
    luogu_4287:双倍回文
    回文自动机学习笔记
    luogu_3645: 雅加达的摩天楼
    python爬今日头条(ajax分析)
    Python多进程multiprocessing.Pool()
    Python爬微博(ajax+mongo)
    python实用函数之join()
    python之tuple与list
  • 原文地址:https://www.cnblogs.com/duanxz/p/4919158.html
Copyright © 2020-2023  润新知