为什么要签名?
1、防止接口被恶意调用,增加服务器的压力
2、保证数据的一致性(即发送和收的的数据一样)
签名校验原理?
1、简单点的理解就是客户端发送{“username”:”jack”,”password”:”aaa123456″}给服务端,通过一个key=”hello world”加入到你的请求体里面,然后通过一系列方式得到一个sign,你的发送数据变成{“username”:”jack”,”password”:”aaa123456″,”sign”:”DKAG663F”}
2、服务端得到数据之后,去除sign字段,得到客户端需要发送的真实请求数据,然后用一样的key=”hello world”,用一样的手段对其进行加密,同样得到一个new_sign,如果sign==new_sign,那证明是自己人请求的,数据也没用被修改,由于key只有我俩自己知道,否则就是他人请求的,给与拒绝
搞清楚为什么要进行签名和签名的基本原理了,目前实现一个简单的签名已经验签,直接上代码,本文是以MD5的方式进行加密,其他的方式基本原理也一样
a、新建一个目录sign_test,目录下我建了三个python文件,get_sign.py,requests_server.py,requests_client.py
b、get_sign.py
import hashlib # 导入模块hashlib
# md5加密算法
def MD5(str):
:param str: 需要加密的字符串
:return: 加密完成的密文
md = hashlib.md5() # 创建md5对象
md.update(str.encode(encoding= utf-8 ))
return md.hexdigest()
# 获取sign签名
def getSign(map: dict, key: str):
:param map: 接口的请求数据
:param key: 客户端与服务端约定的key
:return: 签名
# 遍历字典,组成特定格式(k1=v1&)字符串的列表
li = [(k, map[k]) for k in sorted(map.keys())]
result = ""
for i in li:
result += i[0] + "=" + i[1] + "&"
# print(result) result=password=aaa123456&username=jack&
result_new = result + key= + key
# print(result_new)result_new=password=aaa123456&username=jack&key=hello
# md5加密,并转为大写。
sign = MD5(result_new).upper()
# 返回sign
return sign #95E34CB05C944D33DE166E03942C83B3
if __name__ == __main__ :
body={"username":"jack","password":"aaa123456"}
key="hello"
sign=get_sign(body,key)
print(sign)
c、requests_server.py,启动一个服务端进行验签
from flask import Flask, request
import json
from flask_cors import CORS
from sign_test.get_sign import get_sign
app = Flask(__name__)
# 允许跨域
CORS(app, resources=r * )
@app.route( /api , methods=[ POST ])
def api():
data = json.loads(request.data)
print("请求体的数据:{}".format(data))
sign = data["sign"]
del data["sign"]
# 将请求的数据去除sign之后,用一样的key去加密,得到一个new_sign
new_sign = get_sign(data, key="hello")
print("服务端的签名:{}".format(new_sign))
# 判断客户端发过来的签名是否与服务端的签名一致
if sign == new_sign:
do something
、、、
、、、
res = {"status": 200, }
return json.dumps(res)
else:
return json.dumps({"status": 500})
if __name__ == __main__ :
app.run(host= localhost , port=8009, debug=True)
d、requests_client.py
from sign_test.get_sign import get_sign
import requests, json
# 主程序
if __name__ == "__main__":
# 加密秘钥
key = "hello"#key是双方约定的,我这边就是直接写死一个,与服务端一直
body = {"username": "alex", "pwd": "123456"}
sign = get_sign(body, key)
body["sign"] = sign
url="http://localhost:8009/api"
res = requests.post(url=url, data=json.dumps(body))
print("请求体body={}".format(body))
print("返回值:{}".format(json.loads(res.content)))
e、保持key=”hello”,启动服务,发送请求
客户端
请求体body={ username : alex , pwd : 123456 , sign : E9C952A9F32719995319149991365D15 }
返回值:{ status : 200}
服务端
请求体的数据:{ username : alex , pwd : 123456 , sign : E9C952A9F32719995319149991365D15 }
服务端的签名:E9C952A9F32719995319149991365D15
签名和验签都是成功的!!!!!!!!!!!!!
f、保持服务端key=”hello”,客户端key=world启动服务,发送请求
客户端
请求体body={ username : alex , pwd : 123456 , sign : DFB02DEE70B5B9D3CD8B446051EF3A84 }
返回值:{ status : 500}
服务端
请求体的数据:{ username : alex , pwd : 123456 , sign : DFB02DEE70B5B9D3CD8B446051EF3A84 }
服务端的签名:E9C952A9F32719995319149991365D15
客户端返回的是500,验签是失败的,因key不一致!!!!
本文采用的是MD5进行的加密,由于MD5加密是不可逆的,所以一般可以用来签名或者校验文件的完整性,原理都是一样的,目前签名和加密用的较多的就是RSA和AES算法,基本上用法都差不多,文中有错误的欢迎指出,有兴趣测试或者开发伙伴欢迎来一起探讨
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...