码迷,mamicode.com
首页 > 编程语言 > 详细

Python API简单验证

时间:2018-08-06 14:36:39      阅读:308      评论:0      收藏:0      [点我收藏+]

标签:def   time   行数据   eth   sci   比较   gif   因此   api   

前言

因为CMDB内部的需求,需要一个API进行数据传输,用来传递需要抓取的服务端信息信息给抓取的autoclient,autoclient抓取好之后再通过API传输到服务器,保存到数据库。但是为了防止恶意的API访问,需要做一个验证。

 

设想一

可以在客户端跟服务端都规定好一串随机字符串做验证,只有当带着这串验证的请求发送过来的时候,才让其进行访问。

技术分享图片

如果学过了爬虫,大家很容易就发现,这串随机字符串在浏览器里面是可以监听的,多观察几次总是会发现的。而且无论通过如何的方式,只要暴露在外面,都是会被察觉的。此时,就需要对其进行加密。

 

设想二

既然随机字符串在web传输中是明文状态,那我们试着将其转换成密文的,转换下思路,如果每次的请求都是随机字符串配合一串一直变动的值进行md5加密,此时,产生的验证字符串也应该变成动态密文。用什么做动态字符串来配合约定好的字符串进行md5加密呢?既然是动态的,时间戳,是最好的选择。   

技术分享图片

此时一切看着都很完美,但是,忽略了一点,无论是不是加密的字符串,http请求的时候都是可以监听到的,所以即使加密,即使不知道怎么加密的,依旧可以直接拿着这串字符串直接进行验证访问。尴尬。。。

 

设想三

其实上面的设想二已经做到了动态,思路上只要改一点就立刻变成可行的了。在http请求的时候,即使是在相当糟糕的网络环境里,也不会需要发送非常长的时间,因此,卡住时间便可以实现。

在拿到client的时间戳是,服务器段只需要跟当前时间戳进行比对,如果时间间隔小于10秒就当作正常访问。就可以了。

技术分享图片上面的设计思路完美的解决了动态的问题,此时不免还有疑问,如果真的会在10s内盗取到字符串直接访问呢?

 

完善思路

基于上面的问题,可以再多加异步验证,写一个列表,访问过的字符串都放在列表里,后面的访问都跟此列表比对下,如果在此列表内,就拒绝访问。

技术分享图片

如上的设计思路就可以解决问题。

优化

最后的设计思路肯定能解决问题,但是也存在一个问题,就是,随着时间进度的推移,访问列表一定会越来越大,始终是不友好的一点。肯定需要给字符串设计一个超时时间。

visited_list = [28g12b12128912e2kj|127381237812391, 829312g12be120e102ej12je91|12312984123123,....]

如果以上述的方式取跟系统时间比较当然是一件很费事的工作,占用很多的IO,可以使用redis来轻松实现这个功能。

 

 

技术分享图片

 

 CBV通过此类装饰方式实现验证

 验证代码

技术分享图片
def api_auth_method(request):
    auth_key = request.META.get(HTTP_AUTH_KEY)
    if not auth_key:
        return False
    sp = auth_key.split(|)
    if len(sp) != 2:
        return False
    encrypt, timestamp = sp
    timestamp = float(timestamp)
    limit_timestamp = time.time() - ASSET_AUTH_TIME
    print(limit_timestamp, timestamp)
    if limit_timestamp > timestamp:
        return False
    ha = hashlib.md5(ASSET_AUTH_KEY.encode(utf-8))
    ha.update(bytes("%s|%f" % (ASSET_AUTH_KEY, timestamp), encoding=utf-8))
    result = ha.hexdigest()
    print(result, encrypt)
    if encrypt != result:
        return False

    exist = False
    del_keys = []
    for k, v in enumerate(ENCRYPT_LIST):
        print(k, v)
        m = v[time]
        n = v[encrypt]
        if m < limit_timestamp:
            del_keys.append(k)
            continue
        if n == encrypt:
            exist = True
    for k in del_keys:
        del ENCRYPT_LIST[k]

    if exist:
        return False
    ENCRYPT_LIST.append({encrypt: encrypt, time: timestamp})
    return True


def api_auth(func):
    def inner(request, *args, **kwargs):
        if not api_auth_method(request):
            return JsonResponse({code: 1001, message: API授权失败}, json_dumps_params={ensure_ascii: False})
        return func(request, *args, **kwargs)

    return inner
auth

 

Python API简单验证

标签:def   time   行数据   eth   sci   比较   gif   因此   api   

原文地址:https://www.cnblogs.com/wuzdandz/p/9429784.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!