API效验

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('验证成功')
原文地址:https://www.cnblogs.com/Afrafre/p/10885075.html