Python 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 Falsesp = auth_key.split('|')if len(sp) != 2:return Falseencrypt, timestamp = sptimestamp = float(timestamp)limit_timestamp = time.time() - ASSET_AUTH_TIMEprint(limit_timestamp, timestamp)if limit_timestamp > timestamp:return Falseha = 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 Falseexist = Falsedel_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)continueif n == encrypt:exist = Truefor k in del_keys:del ENCRYPT_LIST[k]if exist:return FalseENCRYPT_LIST.append({'encrypt': encrypt, 'time': timestamp})return Truedef 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?
轉載于:https://www.cnblogs.com/wuzdandz/p/9429784.html
總結
以上是生活随笔為你收集整理的Python API简单验证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript高级特征之面向对象笔
- 下一篇: jira java接口生成问题