为了防止信息被篡改和伪造,保障通信对安全,在app对请求参数中常使用MD5、RSA、SHA等签名算法。下面以MD5为例学习一下:
MD5参数签名
1、服务器和客户端约定一个salt (salt不参与通信,只要不泄漏,一般请求就不会被伪造)
2、按照指定顺序将所有参数排序,然后生成一个字符串
下面以一个简单对例子来讲解:
参数为:uid=12343546,noncse=8ec4560998,from=3
排序为:from=3,uid=12343546,noncse=8ec4560998,
拼接字符串:from=3uid=12343546noncse=8ec4560998
生成签名参数sign: (python语言代码)
import hashlib,random
def calc_sign_md5(params_dict):
"""
根据参数列表计算sign值
:param params_dict: 参数列表
:return: md5加密后的sign值
"""
dict = params_dict
keys = sorted(dict.keys())
string = ""
for key in keys:
if dict[key] != '':
string = string + str(key) + '=' + str(dict[key]) + '&'
articleId = string + 'S}34546575*8wL7i'
hash = hashlib.md5()
hash.update(articleId.encode('utf-8'))
return hash.hexdigest()
app发送请求时将sign一起上传:uid=12343546,noncse=8ec4560998,from=3,sign=5b049bda2977beb29755b977b38b5c4b
服务器对sign参数进行验证,验证通过才返回数据,否则返回错误信息。
请求的唯一性
为了防止重复请求,通常采用timestamp+nonce方案。
timestamp:参数中加入时间戳
nonce:随机生成字符串
假设允许客户端和服务器之间最多存在15分钟的时间差,同时追踪记录在服务端的nonnce集合。当有新请求进入时:
1、首先验证时间戳误差。如果超出范围则返回错误信息。
2、时间戳验证通过:则查询携带的nonce。如果nonce已经存在,则返回错误信息。
3、时间正确、nonce也不存在的情况:记录nonce,删除集合内大于15分钟的nonce
4、验证sign
params["timestamp"] = int(time.time()) * 1000
def calc_noncestr(self):
"""
随机生成一个16位字符串作为参数noncestr
:return: 生成的参数noncestr值
"""
seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
sa = []
for i in range(16):
sa.append(random.choice(seed))
return ''.join(sa)
请求参数变为:uid=12343546,noncse=8ec4560998,timestamp=1550492925,noncestr=CWKADuTJVqjdAu5B,from=3,sign=5b049bda2977beb29755b977b38b5c4b
登录验证
需要登录的接口如何验证:
1、客户端提供用户名和密码,服务器返回session
2、客户端发送请求的时候将session作为参数上传
session一般有时效,过期需要重新获取