API验证
API驗證
在web應(yīng)用中,服務(wù)端提供的API接口必須有某種安全機(jī)制,來識別Http請求是否合法,以防別有用心之人截獲http請求,對服務(wù)端進(jìn)行攻擊的行為。這里,參考Tornado簽名cookie源碼,來實現(xiàn)一個API驗證的功能。
基本思路:
下面我們在Django中實踐一下:
新建項目API_AUTH,創(chuàng)建應(yīng)用app01,定義路由如下:
from django.conf.urls import url from app01 import viewsurlpatterns = [url(r'^api_auth/$', views.api_auth), ]寫一個腳本test.py,通過request模塊對上述路由發(fā)起Http請求
import requests, time, hashlibkey = 'asdgasgewfqsef' url = 'http://127.0.0.1:8000/server.html'# 將key與當(dāng)前時間加密生成動態(tài)密鑰tokentimestamp = time.time() temp = '{key}|{time}'.format(key=key,time=timestamp) md5_str = hashlib.md5(temp.encode('utf-8')).hexdigest() token = '{md5_str}|{time}'.format(md5_str=md5_str, time=timestamp)# 在Http請求頭中攜帶tokenresponse = requests.get(url, headers={"auth-key": token}) print(response.text)# 模擬超時發(fā)送請求fake = token time.sleep(6) response = requests.get(url, headers={'auth-key': fake}) print('second...',response.text)說明:
服務(wù)端api_auth視圖函數(shù):
def api_auth(request, *args, **kwargs):key = 'asdgasgewfqsef' # 服務(wù)端與客戶端持有同樣的keytemp_key = {# client_md5: timestamp --> 過期自動清除, 判斷是第一次請求# 通過redis,Memcache來做過期自動清除}token = request.META.get('HTTP_AUTH_KEY') # 提取請求頭中的密鑰print('token...',token)# 6e632f8e858e07ffcc3b636a1577121b|1506983215.7659595# 分割出客戶端動態(tài)key和時間字符串client_md5 = token.split('|')[0]timestamp = token.split('|')[1]# 用客戶端的時間字符串和服務(wù)端的key,生成服務(wù)端動態(tài)keytemp = '{key}|{time}'.format(key=key, time=timestamp)server_md5 = hashlib.md5(temp.encode('utf-8')).hexdigest()now = time.time()if float(timestamp) + 5 < now: # 5s過期驗證return HttpResponse('呵呵')elif server_md5 != client_md5: # 動態(tài)key驗證return HttpResponse('呵呵')elif temp_key[client_md5]: # 第一次訪問驗證return HttpResponse('呵呵')else: # 驗證通過,將這次的請求的動態(tài)key和時間戳作為記錄保存,以作下次第一次訪問驗證。temp_key[client_md5] = timestamp return HttpResponse('驗證通過')說明:
封裝成裝飾器,可以給需要的視圖函數(shù)使用
def api_auth(func):def deco(request, *args, **kwargs):key = 'asdgasgewfqsef' # 服務(wù)端與客戶端持有同樣的key# 同上......now = time.time()if float(timestamp) + 5 < now: # 5s過期驗證return HttpResponse('呵呵')elif server_md5 != client_md5: # 動態(tài)key驗證return HttpResponse('呵呵')elif temp_key[client_md5]: # 第一次訪問驗證return HttpResponse('呵呵')else: # 驗證通過,將這次的請求的動態(tài)key和時間戳作為記錄保存,以作下次第一次訪問驗證。temp_key[client_md5] = timestampreturn func(request, *args, **kwargs)return deco@api_auth def view_func():pass總結(jié)
- 上一篇: 对象序列化机制的理解
- 下一篇: ajax callback 在什么时候运