1.问题描述:
接口测试时,url 中 GET 传参时需要对 query 部分加密,再进行 url 拼接,加密规则如下
1.假设 query 部分有 3个参数,先对传参内容根据 key 字典升序排序,再进行拼接得到字符串qs
2.每个用户有自己的 apikey,qs 拼接 时间戳和apikey,得到 qf
3.对 qf 进行 md5 加密,得到 hash 值
4.最终 url = host + path + qs + 时间戳 + hash
传入参数:name:jx,age:21,school:NCUT
1.根据字典序:qs = age=21&name=jx&scool=NCUT
2.假设当前的时间戳为 123,apikey为xxx qf = qs&time=123&apikey=xxx
3.hash = md5(qf)
4.url = host/path?qs&time=123&hash
最初的 Python代码:(加密算法为 thqs)
def thqs(dict, apikey):
# 1. 字典序排序
sorted_dicts = sorted(dict)
qs = ''
for key in sorted_dicts:
qs += key + '=' + dict[key] + "&"
# 2. 添加时间戳和apikey
UnixTime = int(time.time())
qf = qs + "time=" + str(UnixTime) + "&salt=" + apikey
# 3.md5 加密
hash = '&hash=' + hashlib.new('md5', qf.encode('utf-8')).hexdigest().upper()
# 4.最终的hqs
hqs = qs + "time=" + str(UnixTime) + hash
return hqs
接口测试报错:
{
"result": "FAIL",
"reason": "invalid encrypt"
}
报错原因:加密错误
2.排查过程:
传入参数为中文则报错,英文则正常
传入英文
{
"result": "OK",
"room": {
"id": "09B280672D9A3F5C9C33DC5901307461",
"atlasRoomId": ""
}
}
3.问题原因:
url GET传参时客户端会先对中文部分进行编码,服务器会对通过解码获取到中文
并且看到开发的接口文档中写到(哭)
编码格式
Live API 只接受 UTF-8 格式编码的信息,返回的数据也都是 UTF-8 编码的。当需要通过 GET 请求传递参数时,QueryString 里面的 value 值都需要进行 URL Encode 之后,再进行THQS加密。
图原文链接:一篇文章彻底解决浏览器发送url带中文参数乱码问题_base64解码后乱码_一篇文章彻底解决浏览器发送url带中文参-CSDN博客
4.代码修改:
拼接 qs 时对 value 进行编码
def thqs(dict, apikey):
# 1. 字典序排序
sorted_dicts = sorted(dict)
qs = ''
for key in sorted_dicts:
qs += key + '=' + quote_plus(dict[key]) + "&"
# 2. 添加时间戳和apikey
UnixTime = int(time.time())
qf = qs + "time=" + str(UnixTime) + "&salt=" + apikey
# 3.md5 加密
hash = '&hash=' + hashlib.new('md5', qf.encode('utf-8')).hexdigest().upper()
# 4.最终的hqs
hqs = qs + "time=" + str(UnixTime) + hash
return hqs
5.补充编码解码规则
5.1 编码
编码规则:不对逗号,句号,下划线,字母数字编码;
URL不能使用的字符(如中文)前会被加上百分号(%)同时转换成十六进制
quote:不对斜线编码
quote_plus: 编码下划线
5.2 解码
unquote()
unquote(string, encoding='utf-8', errors='replace')
不解码加号,默认string的编码utf-8
unquote_plus()
unquote_plus(string, encoding='utf-8', errors='replace')
加号解码为空格 默认string的编码utf-8