API效验
客户端
import hashlib
import time
import requests
def get_hosts():
# 这里要获取未收集信息的服务器(get 请求要 API验证,并不是所有人进行请求都可以)
'''
hashlib值: token|time 进行hash
发送格式: hashlib值| ctime
'''
ctime = time.time()
row_token = 'djoafjaoej'
tmp = '%s|%s' %(row_token ,ctime)
tmp = tmp.encode('utf-8')
m = hashlib.md5(tmp)
client_token = m.hexdigest()
client_token ='%s|%s ' %(client_token ,ctime)
res = requests.get('http://127.0.0.1:8661/asset/',headers={'token':client_token})
print(res)
get_hosts()
服务端
'''
说明:
1. 根据客户传来的数据进行拆分出time
2. 通过同样的加密方式进行加密
3. 三层效验
第一层:超时效验
第二层:双方加密字符串效验
第三层:每个token只能使用一次
'''
print('进入get请求')
# 在连接数据库之前要进行api 效验(确保不是黑客)
row_token = 'djoafjaoej'
server_ctime = time.time()
client_toke n =request.META.get('HTTP_TOKEN')
print('client_token' ,client_token)
token_dic ={}
'''
client_token格式: hash值|ctime
三次阻拦: 时间不能超过10秒,
token要对应,
一个token只能使用一次
(放入字典中进行比对,超过10秒的字典中删除)
token_dic{ client_token: client_ctime}
'''
hash_toke, client_ctime = client_token.split('|')
print('aaa', client_ctime)
# 第一层检验
if server_ctime - float(client_ctime) > 10:
print('错误,超时操作')
return HttpResponse('错误,超时操作')
# 第二层效验
print('加密数据', row_token, client_ctime)
tmp = '%s|%s' % (row_token, client_ctime)
tmp = tmp.encode('utf-8')
m = hashlib.md5(tmp)
server_token = m.hexdigest()
print('server_token', server_token)
if server_token != hash_toke:
print('token验证失败')
return HttpResponse('token验证失败')
'''
# 第三层效验(在token验证成功的基础上)
# 一个token 只能用一次
# 先遍历字典,将超过10秒的数据删除
for k in list(token_dic.keys()):
v_time = token_dic[k]
if float(v_time) - server_ctime > 10:
# 删除该条记录
del token_dic[k]
if client_token not in token_dic:
token_dic[client_token] = client_ctime
print('通过检验,可以连接数据库取出为采集信息的服务器,然后将主机名返回')
return HttpResponse('通过检验,可以连接数据库取出为采集信息的服务器,然后将主机名返回')
else:
print('token 已使用过')
return HttpResponse('token 已使用过')
'''
# 第三层用redis
# token_dic{ client_token: client_ctime}
# django中使用redis( 配置文件中进行配置,视图函数中导入)
conn = get_redis_connection()
redis_client_token = conn.get(client_token)
print('存入redis的数据类型', type(client_token), type(client_ctime))
if not redis_client_token:
# 数据库中没有,说明是第一次,验证成功,然后加入数据库设置过期时间
print('通过第三次验证!')
conn.set(client_token, client_ctime, 5)
return HttpResponse('验证成功')