命令模式和RESTful的抉择
首先,我们查看微信的API,它使用的是类RESTful服务的实现,每个功能都有各自的URI。
微信API的示例如下。
下单:
https://api.mch.weixin.qq.com/pay/unifiedorder
查单:
https://api.mch.weixin.qq.com/pay/orderquery
可见,下单和查单的API具有相同的URI前缀:https://api.mch.weixin.qq.com/pay,各自的后缀为unifiedorder和orderquery。
然后,我们再来查看一下支付宝支付的API的设计,它使用的是命令模式,
所有的功能都使用同一个URI。
统一的URI:
https://openapi.alipay.com/gateway.do
在HTTP协议中,提供了一个方法参数:method,通过方法参数来传递具体使用的功能,不同的方法表示使用不同的操作。
下单:
alipay.trade.pay
查单:
alipay.trade.query
我们看到,支付宝使用命令模式,只提供了一个统一的URI,然后通过method参数来表示具体调用那个功能和操作。
对比微信支付的RESTful服务和支付宝支付的命令模式,各有优缺点。
两种方式的有点如下。
- 对于命令模式,URI的设计比较简单,只需要设计统一的URI即可,具体选择哪个功能都在method中来表示,method参数易于扩展,扩展时不需要对URI和以及7层代理的URI路由进行修改,只需要对后端代码进行修改即可,对后期增加更多的命令和操作提供了方便。
- 对于RESTful模式,每个功能和操作都有一个对应的URI,对于开发者来说学习起来比较简单,使用起来比较方便,URI信息是在HTTP头上进行传递的,由于URI的不同,在7层代理可以灵活配置分流和路由,这通常在迁移的过程中是需要的。
我们看到这两种方式各有优点,实际上,命令模式代表中心化的思想,而RESTful模式代表的是分而治之的思想,有的时候优点就是缺点儿,缺点就是优点,其实是个博弈。
命令模式是中心化的思想,比较封闭,虽然对将来的扩展实现比较容易,但是失去了简单易懂的优点。而RESTful是分而治之的思想,保持原汁原味的简单API的风格,看到URI就知道API的功能,简单易懂,方便使用。
这里,通过一个比喻来对比命令模式和RESTful模式,想象一下桌子上有3个杯子,杯子里面装着水、酒、雪碧,看起来都是透明的,如果每个杯子都没有标签,我们得拿起挨个尝一下,才知道哪个是水、酒或者雪碧,这就像命令模式一样,URI长得一样,想知道它是干什么的需要进一步看内部的参数,除了看起来麻烦,这在七层代理分流的时候,也是需要解析HTTP体才能看到method参数,性能偏低,然而,如果我们在杯子上加了标签,我们一眼就看出哪个是水、酒或者雪碧,这就像在7层代理需要分流的时候,直接在HTTP头中获取URI,做不同的事儿。
B2B API的安全策略
API接口属于典型的B2B的产品,对安全的要求比较特殊,需要验证企业的身份,这和用户端APP的安全技术栈不同,B2B的API产品通常通过签名和加密来保证安全。
要实施签名和加密安全策略,通常我们会进行抉择是用签名还是加密呢?用对称加密还是非对称加密?
这还是要从需求说起,安全需求也是需求的一种,我们总结安全需求无非这几种:
- 防篡改
- 防偷窥
- 防泄漏
- 防抵赖
- 防中间人攻击
要满足这些安全需求,我们采用不同的安全策略和方法,我们从密码学的历史开始说起,这一共经理了3个时代。
-
算法加密时代
在很久以前,没有各种加密算法,为了防止软件被盗用,通常一般在软件中预留了一段加密算法,如果用户输入的注册码满足算法的需求,就通过了校验,这个时代叫做算法加密时代,以算法为核心来验证身份,但是这种方法有明显的缺陷,只要有足够强大的技术力量,算法都是可以被破解的。
-
对称加密时代
这一时代,发明了对称加密算法,加解密方约定同一个秘钥,加密方用密匙加密,解密方用同一个密匙解密,如果可以成功解密,说明加解密方都有权限访问数据。对称加密有两个应用场景,一个就是签名,一个就是用来加密,对称加密和对称签名都是使用的对称加密算法,但是目的不一样,签名就想盖章一样,防止被篡改,而对称加密则是为了防止偷窥和防止泄漏。但是这一时代的对称加密算法也有个明显的缺点,就是加解密双方约定了同一个秘钥,加解密双方理论上都是可以抵赖的,如果秘钥泄露了,对可以说是对方泄露的,是无法判断是谁把秘钥泄露了。
这一时代著名的算法有3DES、AES。
-
非对称加密时代
到了非对称加密时代,解决了对称加密带来的抵赖问题,这一时代可以生成1对秘钥,1对秘钥由公钥和私钥组成,公钥加密数据只能有私钥来解密,私钥加密数据只能由公钥来解密,前者正式加密的应用场景,而后者是签名的应用场景。著名的SSL就是使用的非对称加密。
这一时代著名的算法有RSA。
了解了这个背景,我们现在来回顾一开始我们提出的安全需求,要满足防篡改,只需要对称的签名即可,要满足防泄露和防偷窥,只要使用对称的加密即可,但是要满足防止抵赖,必须使用非对称签名和非对称加密。
但是要满足防止中间人攻击,那么,我们需要使用双向的非对称安全验证,通常使用双向的SSL来保证。
在支付行业里面的实践中,为了安全以及合规需求,我们通常需要使用非对称签名来保证数据不被篡改,使用非对称加密保证敏感数据不泄露,如果有出款需求,我们一般使用非对称的双向SSL证书来保证出款的安全。
阅读更多关于“从微信支付宝支付接口设计谈API接口产品的设计经验和最佳实践”的内容,请报名参加gitchat的唠嗑节目。