APP 端签名方案

2022-09-29 15:35:32 浏览数 (1)

支持方法

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 内,发送请求。

0 人点赞