关于JSON转字符串后前端与python得到的结果不一致的问题,及对象按key排序
背景:
哈希码参数校验防参数篡改。前端下发接口时对参数按约定秘钥和逻辑进行加密,后端在获取到请求后对请求参数以同样的秘钥和逻辑加密计算得出哈希值,再与请求的哈希值对比,如果不一致则证明参数被篡改。
前端代码:
对json对象进行了按key排序
1 let dataTmp = this.deepClone(data); 2 3 let dataStr:string 4 5 dataStr = JSON.stringify(dataTmp, Object.keys(dataTmp).sort()) 6 return CryptoJS.HmacSHA256(dataStr, key).toString(CryptoJS.enc.Hex)
python代码:
1 import json 2 return json.dumps(datas)// 排序和加密代码省略
错误结果原因:
对相同的参数进行计算前后端得出的结果不一致,经查阅相关资料(JSON.stringify和json.dumps源码)得知,不一致原因是空格的不同导致。JSON.stringify默认(0)是没有空格,而json.dumps默认(None)是1个空格,而且二者在设置空格数1时对第一个key之前的空格表现也不同。1时JSON.stringify第一个key前仍有空格('{\n "a": 1\n}'),而json.dumps没有。经测试0.5时JSON.stringify可以去除第一个key前的空格('{\n"a": 1\n}')。因而设置空格数1以上时,前后端可以得到相同结果。
正确结果编码:
前端:
1 let dataTmp = this.deepClone(data); 2 3 et dataStr:string 4 5 dataStr = JSON.stringify(dataTmp, Object.keys(dataTmp).sort(),4) 6 return CryptoJS.HmacSHA256(dataStr, key).toString(CryptoJS.enc.Hex)
python:
1 import json 2 return json.dumps(datas,indent=4)
FIGHTING