TMF
简介
网关服务+开发框架
客户端 ———HTTP/TCP———>网关———HTTP/RPC———> 服务器
客户端会将请求数据发送到网关,网关解析到数据后会根据该URL配置项中的HTTP/RPC将数据转发到对应的业务服务器;然后业务服务器处理完成后将数据返回给网关,网关再将数据返回给客户端。
请求路径
原生路径:
sharkinit->xxfunc-(sharkUtil)->sendshark
一般会对shark进行封装,例如LoginActivity->SharkUtil.request(“login.do”)->Shark.sendshark
H5路径
xx.js($rpcDo)→app.js->TMFJSBridge.js→ITMFWebView->BaseTMFWeb->findjsapi->xxjsapi->sendshark->oncallback
js请求通过TMFJSBridge调用webview中注册的js接口,webview初始化时会将已实现的JsApi接口类和接口名称关联(Map),所以js中通过接口名即可调用java层函数
实现JsApi接口
Shark
鲨鱼皮作为网关组件,其包含了数据格式处理、加解密、通讯
- 初始化Shark
- 获取配置
- Build
- Start
Shark初始化需要获取程序Context,一般为Application:
1
Shark.setAppContext(this);
Shark需要从TMFconfig配置中获取应用ID、协议类型、网关等信息。
创建一个Shark实例:
1 | Shark shark = SharkFactory.builder(context) |
最后启动shark:
1 | shark.start(autoStartTcpChannel) |
关键函数:
serviceFactory
设置线程池和加解密算法,需要实现一个IServiceFactory接口,框架提供默认的SM2和SM4:
sendShark
两个参数SharkHttpEntity、 ISharkCallBack2
SharkHttpEntity:是封装的请求或响应结构,sendShark中对应参数为请求包对象
ISharkCallBack2:网络请求回调接口,接口需要实现onFinish,最后一个参数也为SharkHttpEntity,则是应答包对象
SharkHttpEntity继承自JceStruct
SharkHttpEntity结构:
参数 | 说明 |
---|---|
params | SashimiHeader对象,header参数集合 |
data | 请求body |
编写请求参数的自吐脚步建议从SharkHttpEntity初始化处入手,shark的加解密接口由于参数已经是SharkHttpEntity结构的byte数组,不好处理。开发为了便利,一般会对SharkHttpEntity进行封装,封装类的入参往往都是String,参数格式一般为json或url格式,容易打印和处理。
应答参数的自吐脚步从ISharkCallBack2的回调函数onFinish中进行回溯,对已经将SharkHttpEntity.data处理成String处进行hook。
通讯过程
- 终端随机生成一个密钥randomKey;
- 用服务器的SM2公钥对randomKey做非对称加密得到secret,并用randomKey 对业务数据做 SM4 对称加密,然后发送给后台;
- 后台用对应的SM2私钥对secret解密得到randomKey,并为其分配一个标识 sessionId,存储 sessionId 和 randomKey 的映射关系;并用 randomKey 对业务数据做 SM4 对称解密,返回的业务数据也用 randomKey 做 SM4 加 密,将 sessionId 和业务数据一起返回给终端;
- 终端收到响应后,后续每次请求都带上该sessionId,并用randomKey数据 进行 SM4 加密;
- 后台收到请求后,根据sissionId找到randomKey,用randomKey对数据进 行 SM4 解密;
- 回包数据也是用randomKey进行SM4加密。
安全性
- 加密算法
64字节SM2、128位SM4,安全
- 通讯安全
密钥协商阶段,密钥传输使用非对称加密;数据传输过程中仅能获取到sessionid和密文,未携带任何密钥信息;sessionid具有时效性;
- 完整性
说是可以在网关到后台直接配置验签服务,客户端没有;
- 抗抵赖
不支持,需要自行添加数字签名。