一、概念
1. 系统参数
不同于业务参数,系统参数是无论如何都要传递给后端的参数。传递时,不与业务参数混在一起,而是在请求header中传输。
2. 秘钥
后端会为每个第三方/调用方设置一个秘钥,需要保密,只有后端代码与第三方/调用方自己知道。该秘钥用于在调用接口前,生成签名,后端在收到请求后,验证签名。
3. 签名
签名由前端生成,并在请求header中传输给后端。只有在前端生成的签名通过了后端的验证后,该请求才算有效。
二、前端
1. 系统参数
系统参数,即为“与业务无关”的参数。
前端调用任何一个后端接口时,均要在request header中传递如下系统参数:
参数名 | 数据类型 | 必输 | 含义 | 备注 |
---|---|---|---|---|
appid | string | Y | 调用方/第三方的系统标识 | 如,hlg(代表火龙果) |
timestamp | long | Y | 调用接口的时间戳 | 如,1598776868036 |
sign | string | Y | md5签名串 | 如,0ca175b9c0f726a831d895e532182008 |
2. 生成签名
2.1 步骤
- 按请求头和请求体分组,每组按参数名排序,并带上参数值,生成一个字符串。
- 在步骤1生成的字符串后,追加秘钥(secret_key),形成一个新串。
- 对步骤2生成字符串做md5加密,生成sign值,附带在header中。
2.2 举例
参数名 | 参数值 |
---|---|
appid | hlg |
timestamp | 1598776868036 |
userName | 张三 |
age | 18 |
birthday | 2020-08-30 |
mobilePhone |
2.2.1 步骤
- 生成字符串"appidhdtimestamp1598776868036age18birthday1990-08-18mobilePhoneuserName张三"。
- 假设为hd这个appid分配的secret_key为123,生成字符串"appidhdtimestamp1598776868036age18birthday1990-08-18mobilePhoneuserName张三secret_key123"。
- md5加密,得到sign=1ff786ca7dbae4c5971743212c722ab7。
2.2.2 请求信息
1. http requet header:
name | value |
---|---|
appid | hd |
timestamp | 1598776868036 |
sign | 1ff786ca7dbae4c5971743212c722ab7 |
2. http request body:
name | value |
---|---|
userName | 张三 |
age | 18 |
birthday | 1990-08-18 |
mobilePhone |
三、后端
1. 参数获取
- 分别在request header和request body中获取到系统参数和业务参数。
- 可以选择把这两组参数分别放在某个集合容器里,例如treeMap,因为这个容器是有序的。
2. 签名验证
- 按照与前端相同的规则,生成签名。秘钥根据appid在db或者枚举中取得。
- 对比前端传来的sign,与后端自己生成的sign是否相同。
- 如果相同,流程继续;如果不同,返回验签失败。
3. 过期失效
- 如果验签成功,则需要进一步验证有效期。
- 取出前端传来的系统参数timestamp,与当前时间戳对比。
- 如果差距在5min之内,认为是有效请求;否则,认为是过期请求,返回请求过期。