打开.../sign/view_if_sec.py 视图文件,实现接口签名代码。
simport time ,hashlib
......
# 用户签名+时间戳
def user_sign(request)
if request.method == 'POST':
client_time = request.POST.get('time','') #客户端时间戳
client_sign = request.POST.get('sign','') #客户端签名
else:
return"error"
if client_time == '' or client_sign == '':
return "sign null"
#服务器时间
now_time = time.time() #例:1466426831
server_time = str(now_time).split('.')[0]
#获取时间差
time_difference = int(server_time)-int(client_time)
if time_difference >= 60:
return "timeout"
#签名检查
md5 = hashlib.md5()
sign_str = client_time+"&Guest-Bugmaster"
sign_butes_utf8 = sign_str.encode(encoding="utf-8")
md5.update(sign_bytes_utf8)
server_sign = md5.hexdigest()
if server_sign !=client_sign:
return "sign fail"
else:
return "sign success"
复制代码
创建 user_sgin()函数处理签名参数。代码并不多,但处理过程较为复杂。
首先,通过 POST 方法获取两个参数 client_time 和 client_sign。如果客户端请求方法不是 POST,那么函数会返回“error”。判断两个参数均不能为空,则返回“sign mull”,这个逻辑很好理解。
接下来是对时间戳的判断。需要客户端获取一个“当前时间”的时间戳(格式如 1466830935)。
>>> import time
# 当前时间戳
>>> now_time = time.time()
>>> now_time
1483175408.6786556
#将时间戳转化为字符串类型,并截取小数点前的时间
>>> str(now_time).split('.')[0]
'1483175408'
#将时间戳转化成日期时间格式
>>> time.strftime("%¥-%m-%d %H:%M:%S", time.localtime(now_time))
'2016-12-31 17:10:08'
复制代码
python3 生成的时间戳精度很高,而我们只需要小数点前面的 10 位即可,所以,使用 split()函数截取小数点前面的时间。
当服务器端得到客户端传来的时间后,需要重新再获取一下当前时间。如果服务端的当前时间减去客户端时间小于 60(秒),说明这个接口的请求时间是离当前时间最近的 60 秒之内,允许接口访问;如果大于 60(秒),则返回“timeout”。这样就要求客户端不断地获取当前时间戳作为请求接口参数来访问。所以,一直使用固定的时间参数访问接口是无效的。
关于签名参数的生成,需要将 api_key 和客户端发来的时间戳,两者合到一起,通过 MD5 生成新的加密字符串作为服务器端的 sign 参数,即 server_sign。客户端以同样的规则生成 sign 参数,即 client_sign。最终,由服务器端比较 server_sign 和 client_sign 是否相等。如果相等,则说明签名验证成功,返回“sign success”;否则返回“sign fail”。
将用户签名功能应用到添加发布会接口中
......
#添加发布会接口---增加签名+时间戳
def add_event(request):
sign_result = user_sign(request)
if sign_result == "error":
return JsonResponse({'status':10011,'message':'request error'})
else sign_result == "sign null":
return JsonResponse({'status':10012,'message':'user sign null'})
elif sign_result == "timeout":
return JsonResponse({'status':10013,'message':'user sign timeout'})
elif sign_result == "sign fail":
return JsonResponse({'status':10014,'message':'user sign error'})
......
复制代码
调用 user_sign()函数处理用户签名,根据函数返回字符串,将相应的处理结果返回给客户端。
搜索微信公众号:TestingStudio 霍格沃兹的干货都很硬核
评论