Loading

python API验证

API验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
API验证:
    a. 发令牌: 静态
        PS: 隐患 key被别人获取
    b. 动态令牌
        PS: (问题越严重)用户生成的每个令牌被黑客获取到,都会破解
    c. 高级版本
        PS: 黑客网速快,会窃取, so要对数据加密
    d. 终极版本
 
 
特点:
   为什么要用API ?
       - 数据在传输过程中,保证数据安全
   你是如何设计的 ?
       - Tornado 中的加密Cookie类似
       - 创建动态key  md5(key + time)|time (Tornado中也是这么做)
       - 限制
         - 第一关: 时间
         - 第二关: 算法规则
         - 第三关: 已访问的记录
       PS: 黑客网速快,会窃取, so要对数据加密

a. 客户端和服务端都有一个相同的key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
客户端把key发给服务端,服务端拿着自己的key和客户端的key做比较
 
###客户端
 
import time
import requests
 
key = "asdfasdfasdfasdf098712sdfs"
 
response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':key})
print(response.text)
 
 
###服务端
 
#print(request.META)
key = request.META.get("HTTP_OPENKEY")
if key != settings.AUTH_KEY:
    return HttpResponse("验证失败")

b. key和时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#客户端和服务端都有一个相同的key
#客户端把加密key和当前时间发给服务端,服务端收到后把客户端发来的时间和自己的key加密
#然后把加密后的字串和客户端的字串比较
 
#客户端
 
    import time
    import requests
    import hashlib
 
    ctime = time.time()
    key = "asdfasdfasdfasdf098712sdfs"
    new_key = "%s|%s" %(key,ctime,)
 
    = hashlib.md5()
    m.update(bytes(new_key,encoding='utf-8'))  #里面是字节数据
    md5_key = m.hexdigest()                    #返回值是字符窜类型
 
    md5_time_key = "%s|%s" %(md5_key,ctime)
 
 
    response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':md5_time_key})
    print(response.text)
 
#服务端
    client_md5_time_key = request.META.get("HTTP_OPENKEY")
 
    client_md5_key,client_ctime = client_md5_time_key.split("|")
 
    temp = "%s|%s"%(settings.AUTH_KEY,client_ctime)
    = hashlib.md5()
    m.update(bytes(temp, encoding='utf-8'))
    server_md5_key = m.hexdigest()
 
 
    if server_md5_key != client_md5_key:
        return HttpResponse("验证失败")

c. 高级版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#客户端和服务端都有一个相同的key
#客户端把加密key和当前时间发给服务端
#服务端验证:
    #1)服务端判断服务器当前的时间是否比客户端时间快10s,如果在10s内通过,有效的杜绝了案例二成千上万的key
    #2)服务器获取客户端时间和自己key加密然后和 客户端获取到的key比较
    #3)删除与现在时间相差10s的数据(之后用memcache,redis)
    #3)在字典里判断是否有这个key,如果有不通过,没有加入字典(之后用memcache,redis)
 
 
 
#客户端
    import time
    import requests
    import hashlib
 
    ctime = time.time()
    key = "asdfasdfasdfasdf098712sdfs"
    new_key = "%s|%s" %(key,ctime,)
 
    = hashlib.md5()
    m.update(bytes(new_key,encoding='utf-8'))  #里面是字节数据
    md5_key = m.hexdigest()                    #返回值是字符窜类型
 
    md5_time_key = "%s|%s" %(md5_key,ctime)
 
    print(md5_time_key)
    response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':md5_time_key})
 
    #黑客获取调用
    #response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':"f610077a7001c53b5a74868c5544b388|1501514254.455578"})
    print(response.text)
 
 
#服务端
    api_key_record ={
    "76942d662d98ebe3b920a7b791bf5040|1501510243.92804":1501510243.92804,
    }
 
 
def asset(request):
 
 
    client_md5_time_key = request.META.get("HTTP_OPENKEY")
 
    client_md5_key,client_ctime = client_md5_time_key.split("|")
    client_ctime = float(client_ctime)
    server_ctime = time.time()
 
    #第一关 时间关
    if server_ctime - client_ctime > 10:
        return HttpResponse("第一关  小伙子,别虎我,太长了")
 
    #第二关 客户端时间和服务端key加密和 客户端的密钥对比
    temp = "%s|%s"%(settings.AUTH_KEY,client_ctime)
    = hashlib.md5()
    m.update(bytes(temp, encoding='utf-8'))
    server_md5_key = m.hexdigest()
    if server_md5_key != client_md5_key:
        return HttpResponse("第二关   规则正确")
 
 
    #以后基于memcache,目前先写入内存删除超过10s的值
    for in list(api_key_record.keys()):
        = api_key_record[k]
        if server_ctime > v:
            del api_key_record[k]
 
 
    #第三关 判断字典里是否有之前访问的key,如果有不通过,没有加入字典
    if client_md5_time_key in api_key_record:
        return HttpResponse("第三关  已经有人来过了")
    else:
        api_key_record[client_md5_time_key] = client_ctime + 10

d. 终极版本

1
2
3
注意: key 是从配置文件获取的
 
装饰器要返回Httpresponse对象
posted @ 2017-08-02 13:55  Meet~  阅读(380)  评论(0编辑  收藏  举报