描述
一般公司對外的接口都會用到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))