支持方法
POSTGET
请求携带 Header 字段
字段名 | 备注 | 是否参与签名 |
---|---|---|
X-App-Version | app 版本 | yes |
X-Device-Id | app 设备 id | yes |
X-Platform | app 设备类型 | yes |
X-Timestamp | unix 时间戳 (秒) | yes, 时间戳与服务器时间戳相差超过60s 则会失败 |
X-App-Key | 业务申请,服务端下发,需要保存在数据库内,客户端切记不能泄露,每一个 appkey 对应一个 appSecret | yes |
X-Nonce | 随机数,客户端可以用 md5(timestamp guid rand(0,1000)) | yes |
X-Signature | 客户端签名结果 | no |
Content-Type | application/josn, application/x-www-form-urlencoded | no |
签名方法
签名字符串:X-App-Key X-App-Version X-Device-Id X-Platform x-Nonce $RequestMethod $RequestPath $Body X-Timestamp
其中 RequestMethod 为请求方法,这里为: POST
RequestPath 为请求路径,比如 /v1/upload
Body 对于 application/json 则直接将整个 json 串 md5 加密后再 base64 字符串
对于application/x-www-form-urlencoded 则首先要将 formData key=value 值按照 key 进行升序排序,按照 key1=value1&key2=value2 方式拼接
对于 GET 方法,则首先要将 queryArgs key=value 值按照 key 进行升序排序,按照 key1=value1&key2=value2 方式拼接。不允许 POST 请求携带 queryArgs
签名算法:
根据 appSecret 利用 hmacsha256 进行签名
appKey 与 appSecret 均为服务端下发,业务需要妥善保管,切勿泄露
服务端验签流程
1、获取 X-Timestamp 并与本地时间戳想比较,相差 > 60s 则直接验签失败。
2、根据 X-App-Key 获取 appSecret 拼接签名字符串获得服务端签名,并与客户端参数 X-Signature 比对,不一致则签名失败。
3、获取 X-Nonce 查找缓存(redis)是否存在此 nonce,如果没有,则创建此 key,并设置失效时间为 60s( 和 timestamp 失效时间一致),如果有,则认为是重放,签名失败。
3、timestamp 合法,签名合法,nonce 合法,则请求合法,继续处理
响应状态说明
状态码分为 http code 与业务自定义 code(在返回 body 里), 签名不通过则 http code 为 403, 签名通过则 http code 为 200,但业务不一定成功,是否成功需判断业务返回状态码是否为 0 。
http 状态码 | 说明 | |
---|---|---|
403 | 签名校验未通过 | |
200 | 签名校验通过,具体业务信息需查看业务返回体 | |
其他:404/50* | 请求不正确或者服务器问题,按标准 http code 处理 |
业务返回状态码 | 说明 | |
---|---|---|
0 | 成功 | |
非 0 | 请求未成功处理 |
示例:
签名校验未通过
HTTP/1.1 403 Forbidden Date: Fri, 26 Mar 2021 08:19:50 GMT Content-Length: 0 Connection: close |
---|
签名校验通过但后端请求出错
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 26 Mar 2021 08:33:29 GMT Content-Length: 47 Connection: close { "data": null, "msg": "server error", "code": 10001 } |
---|
签名校验通过且后端返回正常
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 26 Mar 2021 08:33:29 GMT Content-Length: 47 Connection: close { "data": $后端返回具体 data 信息, "msg": "success", "code": 0 } |
---|
示例
x-app-key: test-app-key
x-app-secret: testSecret
最终请求参数:
POST http://localhost:8009/sign Content-Type: application/json X-App-Version: test-app-version X-Device-Id: test-deviceid X-Platform: test-platform X-Timestamp: 1616663792 X-App-Key: test-app-key X-Nonce: test-noce X-Signature: dd4cab132d5ef7d0f14967e7483d5501e5df948e1c1105fbe5c7992f9094a722 { "t0":"v2", "t1":"v3", "t2":"v1" } |
---|
签名过程:
1、对请求 body
{ "t0":"v2", "t1":"v3", "t2":"v1" } |
---|
进行 md5 然后 base64 得到字符串:MDljMzZiMGYxZGQxN2UxOTRhNWVmMWFhOTcxYTYwNzI= 请使用标准 base64, 结果内不要带换行符
2、按照 X-App-Key X-App-Version X-Device-Id X-Platform x-Nonce $RequestMethod $RequestPath $Body X-Timestamp 拼接后得到字符串:
test-app-keytest-app-versiontest-deviceidtest-platformtest-nocePOST/signMDljMzZiMGYxZGQxN2UxOTRhNWVmMWFhOTcxYTYwNzI=1616663792, 其中 timestamp 取 unix 时间戳(秒)
3、对 2 得到的字符串进行 hmac256("testSecret", "test-app-keytest-app-versiontest-deviceidtest-platformtest-nocePOST/signCcNrDx3RfhlKXvGqlxpgcg==1616663792") 得到签名结果:
4183f154326ddbbcdd7e350e0a6d8c106da389fe2b54e895165f13af88089e81
4、 将 3 得到结果放入 请求 Header X-Signature 内,发送请求。