API验证

来源:互联网 发布:阿里云代码托管 收费吗 编辑:程序博客网 时间:2024/06/04 19:31

为提高数据库安全,有必要对通过API的来访者进行判断是否为合法客户端。

通过验证签名方式。将key提前放在合法客户端,访问服务端时将key放在请求头,服务端进行验证是否为合法key。

但此方式,key是明文,被截获则泄漏。所以,必须加密。

在客户端通过MD5加密发送key,服务端收到后,取出存在服务端的key加密后比对收到的密文。

自此,我们实现密文发送。但是,密文被截获后仍然可以直接登录服务端,所以,密文必须是变化的。

我们将客户端发送的密文改为key与时间戳的组合的加密后结果,实现密文每一次都不同,并将时间戳放入请求头。在服务端收到密文后,通过从请求头中取出时间戳,并与key 组合加密后 与 密文比对,来执行验证。

然后,我们发现过去产生的所有密文都可以通过验证。

我们必须加入对密文时效性的限制。我们在请求头取出时间戳后将与当前时间戳比对,如超过一定时间则无法通过验证。

我们又考虑,黑客在截获密文后马上访问可能可以赶在密文失效前访问,所有我们将使用过的密文记录在服务端,当密文已经使用,那当前访问便无法通过验证。


client

def md5(arg):    hs = hashlib.md5()    hs.update(arg.encode('utf-8'))    return hs.hexdigest()key = "asdfuasodijfoausfnasdf"ctime = str(time.time())new_key = "%s|%s" %(key,ctime,) # asdfuasodijfoausfnasdf|时间戳md5_str = md5(new_key)# 6f800b6a11d3f9c08c77ef8f77b2d460  # asdfuasodijfoausfnasdf|时间戳auth_header_val = "%s|%s" %(md5_str,ctime,) # 6f800b6a11d3f9c08c77ef8f77b2d460|时间戳print(auth_header_val)response = requests.get('http://127.0.0.1:8000/api/test.html',headers={'auth-api':auth_header_val})print(response.text)

server

def md5(arg):    hs = hashlib.md5()    hs.update(arg.encode('utf-8'))    return hs.hexdigest()key = "asdfuasodijfoausfnasdf"# redis,Memcachevisited_keys = {    # "841770f74ef3b7867d90be37c5b4adfc":时间,  10}def api_auth(func):    def inner(request,*args,**kwargs):        server_float_ctime = time.time()        auth_header_val = request.META.get('HTTP_AUTH_API')        # 841770f74ef3b7867d90be37c5b4adfc|1506571253.9937866        client_md5_str, client_ctime = auth_header_val.split('|', maxsplit=1)        client_float_ctime = float(client_ctime)        # 第一关 时效性验证        if (client_float_ctime + 20) < server_float_ctime:            return HttpResponse('时间太久了,再去买一个吧')        # 第二关: 加密规则        server_md5_str = md5("%s|%s" % (key, client_ctime,))        if server_md5_str != client_md5_str:            return HttpResponse('休想')        # 第三关: 是否已使用密文        if visited_keys.get(client_md5_str):            return HttpResponse('你放弃吧,来晚了')        visited_keys[client_md5_str] = client_float_ctime        return func(request,*args,**kwargs)    return inner@api_authdef test(request):    return HttpResponse('正常用户')







原创粉丝点击