描述
一般公司对外的接口都会用到sign签名,对不同的客户提供不同的apikey ,这样可以提高接口请求的安全性,避免被人抓包后乱请求。
sign签名是一种很常见的方式
#!/usr/bin/env python # -*- coding:utf-8 -*- import urllib.parse import hashlib import requests import json #_______________________签名方式一___________________________________________________ def sign_body(body, apikey): '''请求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)) # 在strA后面拼接上apiKey得到striSignTemp字符串 striSignTemp = strA+apikey # MD5加密 def jiamimd5(src): m = hashlib.md5() m.update(src.encode('UTF-8')) return m.hexdigest() sign = jiamimd5(striSignTemp.lower()) # 得到sign签名后新的body值 body["sign"] = sign return body if __name__ == '__main__': apikey = "12345678" # 验证密钥,由开发提供 body = { "username": "test", "password": "123456", "mail": "", "sign": "" } print(sign_body(body, apikey=apikey)) ##_____________________________签名方式二___________________________________ def _getSign(params, key): change = ksort(params) encode_param = urllib.parse.urlencode(change) decode_param = urllib.parse.unquote_plus(encode_param) encode_str = decode_param + key m = hashlib.md5() m.update(encode_str.encode('utf-8')) sign = m.hexdigest() return sign def ksort(d): return [(k,d[k]) for k in sorted(d.keys())] if __name__ == '__main__': key='288jieu439ji2hik48je3jlo9806hw1' body = { "username": "test", "password": "123456" } body['sign']=_getSign(body,key) print(body)
实际案例:
#!/usr/bin/env python # -*- coding: utf-8 -*- import urllib.parse import hashlib import requests import json #_____________________________________________客户端提交________________________________________________ def _getSign(params, key): '''数据加密处理''' change = ksort(params) encode_param = urllib.parse.urlencode(change) decode_param = urllib.parse.unquote_plus(encode_param) encode_str = decode_param + key m = hashlib.md5() m.update(encode_str.encode('utf-8')) sign = m.hexdigest() return sign def ksort(d): '''遍历字典转成list''' return [(k,d[k]) for k in sorted(d.keys())] def get_address(name,time): data = { "_name": name, "_time": time } key='288jieu439ji2hik48je3jlo9806hw1' #开发提供的key data['sign']=_getSign(data,key)#调用签名函数,并追加到data print('提交请求数据:',data) r=requests.post('http://127.0.0.1:8000/addes',params=data) _json=json.loads(r.text) print(_json) if __name__ == '__main__': get_address('李小龙', 1523803489) #__________________________________________服务端验证sign_______________________________________________ ''' 判断sign是否与客户端一致即可 ''' def _getSign(params, key): del params['sign']#把sign删除了在加密验证 change = [(k,params[k]) for k in sorted(params.keys())] encode_param = urllib.parse.urlencode(change) decode_param = urllib.parse.unquote_plus(encode_param) encode_str = decode_param + key #print(encode_str)#把所有提交的数据及key拼接加密 m = hashlib.md5() m.update(encode_str.encode('utf-8')) sign = m.hexdigest() return sign if __name__ == '__main__': bb={'_time': 1523803489, '_name': '李小龙', 'sign': '9e25aff882368aebc175316ee53b8f38'}#这里是客服端提交的数据 key='288jieu439ji2hik48je3jlo9806hw1' print(_getSign(bb,key))