httprunner学习24-sign签名验证

前言

一般公司对外的接口都会用到sign签名,对不同的客户提供不同的apikey ,这样可以提高接口请求的安全性,避免被人抓包后乱请求。
sign签名是一种很常见的方式
关于sign签名的可以参考前面一篇的介绍https://www.cnblogs.com/yoyoketang/p/11742187.html

接口sign签名

一登陆的接口请求为例,如下接口抓包报文信息,其中sign的签名规则如下

  • 第一步,拼接字符串,首先去除sign参数本身,然后去除值是空的参数p3,剩下p2=v2&p1=v1&method=cancel&pn=vn,
  • 然后按参数名字符升序排序,method=cancel&p1=v1&p2=v2&pn=vn.
  • 第二步,然后做参数名和值的拼接,最后得到methodcancelp1v1p2v2pnvn
  • 第三步,在上面拼接得到的字符串后加上验证密钥apikey,我们假设是abc,得到新的字符串methodcancelp1v1p2v2pnvnabc
  • 第四步,然后将这个字符串换为小写进行md5计算,假设得到的是abcdef,这个值即为sign签名值。
    注意,计算md5之前请确保接口与接入方的字符串编码一致,如统一使用utf-8编码或者GBK编码,如果编码方式不一致则计算出来的签名会校验失败。
POST http://127.0.0.1:8000/api/v3/login HTTP/1.1User-Agent: FiddlerContent-Type: application/jsonHost: 127.0.0.1:8000Content-Length: 111{ "username": "test", "password": "123456", "sign": "1aca01806e93bb408041965a817666af"}HTTP/1.1 200 OKDate: Sat, 26 Oct 2019 03:38:31 GMTServer: WSGIServer/0.2 CPython/3.6.0Content-Type: application/jsonVary: Accept, CookieAllow: POST, OPTIONSX-Frame-Options: SAMEORIGINContent-Length: 109{"code": 0, "msg": "login success!", "username": "test", "token": "a76ba3b8fcbdff82f6a94e5ad5bf8fb934192e5f"}

httprunner脚本

使用httprunner框架写脚本

- config: name: logincase variables: {}- test: name: login case1 request: url: http://127.0.0.1:8000/api/v3/login method: POST headers: Content-Type: application/json User-Agent: python-requests/2.18.4 json: username: test password: "123456" setup_hooks: - ${setup_request($request)} validate: - eq: [status_code, 200] - eq: [headers.Content-Type, application/json] - eq: [content.msg, login success!] - eq: [content.code, 0]

setup_hook函数

在debugtalk.py 编写setup_hook函数,对请求的body部分预处理

import hashlibdef sign_body(body, apikey="12345678"): '''请求body sign签名''' # 列表生成式,生成key=value格式 a = ["".join(i) for i in body.items() if i[1] and i[0] != "sign"] # print(a) # 参数名ASCII码从小到大排序 strA = "".join(sorted(a)) # print(strA) # 在strA后面拼接上apiKey得到striSignTemp字符串 striSignTemp = strA+apikey # 将strSignTemp字符串转换为小写字符串后进行MD5运算 # MD5加密 def jiamimd5(src): m = hashlib.md5() m.update(src.encode('UTF-8')) return m.hexdigest() sign = jiamimd5(striSignTemp.lower()) # print(sign) return signdef setup_request(request): '''setuphook函数,发请求前预处理''' body = request.get("json") print(body) # 由body请求参数生成sign值 sign = sign_body(body, apikey="12345678") print("sign值:%s" % sign) request["json"]["sign"] = signif __name__ == '__main__': body = { "username": "test", "password": "123456" } print(sign_body(body))

运行用例

D:\soft\HELL\DEMO>hrun login_sign_demo.ymllogin case1{'username': 'test', 'password': '123456'}sign值:1aca01806e93bb408041965a817666afINFO POST http://127.0.0.1:8000/api/v3/loginINFO status_code: 200, response_time(ms): 689.84 ms, response_length: 109 bytesINFO start to validate..----------------------------------------------------------------------Ran 1 test in 0.698sOKINFO Start to render Html report ...INFO Generated Html report: D:\soft\HELL\DEMO\reports\1572062969.htmlD:\soft\HELL\DEMO>

相关文章