概述
SHCP――Simple HTTPCommunication Protocol,简单的HTTP通信协议。
本文章提供一种设计思路,能够设计基于http协议的通信层,从安全性、灵活性与数据传输性能上提供一种设计的参考。
在以下场合,本文能提供较好的参考价值:
l 开放平台接口:业界巨头都在做。
l 企业系统服务集成:企业级常见的需求。
l 跨硬件平台统一服务:采用同一套后台通信协议支持PC,移动等设备调用。
关于http通信的名称解析
URL参数
是指直接放在url地址上的参数,例如:http://www.123.com?p1=123&p2=abc,其中p1和p2就是URL参数。
注:只是方便说明在开发过程中的常见概念,该名称并非http报文协议的正式名称。
POST内容
是指存放在http协议报文体中的内容。
注:只是方便说明在开发过程中的常见概念,该名称并非http报文协议的正式名称。
ContentType
用来说明POST内容的类型,http协议分请求和响应两个阶段,并且请求时的ContentType与响应时的ContentType不一定相同,例如:
请求时ContentType= application/x-www-form-urlencoded
响应时ContentType=text/json
常见的http调用需求
因为http协议的特殊性,区分了URL参数和POST内容,根据这两种传参方式,能够组合出多中调用传参情况。
需求情景 | 传参方式 | 返回 |
通过http调用进行业务调用 | URL参数,GET | 业务数据(XML/JSON) |
URL参数+POST内容,POST | ||
通过http调用加载文件 | URL参数,GET | 文件流 |
URL参数+POST内容,POST | ||
通过http调用上传文件 | URL参数+POST内容,POST | 业务数据(XML/JSON) |
SHCP关键参数
SHCP协议中预先设计了一些关键的URL参数。URL参数均以下滑线先开头,避免与其他业务URL参数冲突。
_lic――license,授权号
用于调用前的授权验证,URL参数,必须,示例:_lic=1001。
_valid――validation,验证号
用于请求方的参数签名和响应方的签名验证,该参数不会在URL参数出现。
_t――timeStamp,时间戳
用于参数签名验证以及解决浏览器端缓存问题,URL参数,必须,格式:yyyyMMddHHmmss,示例:_t=20131231235959。
_sign,参数签名
内容是MD5加密字符串,签名生成规则在后文说明,URL参数,必须,示例:_sign={MD5字符串}
_sm――signMode,签名方式
用于说明参数签名的验证方式,数值必须是:1、2、3,URL参数,可选,缺省为1,示例:_sm=3
signMode数值说明:
l 1代表只签名URL参数
l 2代表只签名POST内容
l 2代表同时签名URL参数和POST内容
_v――version,版本号
SHCP协议版本号,URL参数,可选,缺省为1.0,示例:_v=1.0。
SHCP的POST内容
SHCP的POST内容支持业务数据、文件流2大类型数据。
业务数据:一般是XML/JSON,自定义的业务数据格式。
文件流:二进制文件数据流,用于加载/上传文件。
POST内容与ContentType的对应关系如下:
POST内容 | ContentType |
业务数据 | zip/data |
文件流 | application/octet-stream |
zip/data如何生成?
把业务数据进行zip压缩,并建立一个压缩节点名称为data的zip数据流,这样做的目的是减少数据传输量。
下图是解压效果,里面的data存储的就是业务数据。
SHCP的安全控制策略
一个http请求接入时要进行的验证如下图:
访问授权验证
对URL参数_lic值的有效性进行验证,_lic和_valid一般是服务处理方提供,相当于用户/密码的概念。
参数签名验证
对URL参数_sign值的有效性进行验证,用于防止数据传输过程中被拦截篡改,_sign的生成校验规则请看下文。
业务数据验证
具体业务级别的验证,根据接口的业务特性进行业务校验。
SHCP的参数签名
参数签名_sign的生成
MD5字符串的准备
MD5字符串 | 生成规则 | 示例 |
URL参数MD5字符串 | 排除关键URL参数_lic、_t、_v、_sign、_sm后,对所有业务URL参数按参数名称进行字符串升序排序,每个参数值去掉前后空白,然后把参数值作字符串拼接,拼接后的字符串采用UTF8编码生成MD5字符串。 | 业务URL参数: api=Sys.Login&user=hunk&pwd=123 排序拼接后的字符串: Sys.Login123hunk UTF8编码生成MD5字符串:
|
POST内容MD5字符串 | POST内容是二进制数据流时直接生成MD5字符串。 POST内容是字符串数据时采用UTF8编码生成MD5字符串。 |
|
_sign的生成规则
签名方式 | 规则 |
1 | 字符串拼接:_lic + _valid + URL参数MD5 + _t |
2 | 字符串拼接:_lic + _valid + POST内容MD5 + _t |
3 | 字符串拼接:_lic + _valid + URL参数MD5 + POST内容MD5 + _t |
_sign = 对拼接字符串采用UTF8编码生成MD5字符串
参数签名_sign的校验
服务方接收数据后,按上述规则生成_sign2,然后比较_sign和_sign2的值,一致时说明接收的数据是合法的,能通过校验。
SHCP的异常处理
异常的返回
异常发生的情景 | 返回 |
|
通过http调用进行业务调用发生异常 | XML: <error> <code>{错误码}</code> <message>{错误描述}</message> <!-- 可以加入自定义的节点 --> </error> JSON: { error:{ code:”{错误码}”, message:”{错误描述}” //可以加入自定义的属性值 } } | |
通过http调用加载文件发生异常 | HTTP 404 |
|
通过http调用上传文件 | 与通过http调用进行业务调用发生异常一致 |
|
错误码与描述
错误码 | 错误描述 | 说明 |
11 | 缺少授权码参数 | 缺少_lic参数 |
12 | 无效的授权码 | _lic被验证不存在 |
13 | 缺少签名参数 | 缺少_sign参数 |
14 | 无效的签名 | _sign被验证错误 |
15 | 缺少时间戳参数 | 缺少_t参数 |
16 | 无效的时间戳参数 | _t参数格式不是yyyyMMddHHmmss |
错误码100以上时用于业务级别错误处理。