API接口认证
restful API接口可以很方便的讓其他系統調用,為了讓指定的用戶/系統可以調用開放的接口,一般需要對接口做認證;
接口認證有兩種方式: 1、認證的token當做post/get的參數,server端拿到該參數后進行比對; 2、將認證的token加到http header中,server端解析header,拿到token進行比對,這也是最常用的方式;
?
下面針對第二種方式,進行詳細的說明:
客戶端請求http 的接口,python提供了requests模塊,可以很方便的實現,在請求的時候,需要將請求的參數和認證的token攜帶過去;但是這樣做,有可能是不安全的,因為token是不變的,在使用的過程中存在泄漏或者http請求被劫持的問題;所以,為了保證安全,最好傳輸的token是加密的,并且是一直變化著的;比較好實現方法是:獲取當前的時間戳,和token拼接之后做MD5加密,發送到server端,server 再根據當前的時間戳和token拼接的字符串做md5,結果和接收到的字符串比對,但問題是數據在網絡中傳輸存在延遲,所以時間戳兩端對不上,所以客戶端在發送的時候,還需要將時間戳一同發過去,所以最終發送的字符串實現如下:
import hashlib import time current_time = str(time.time()) m = hashlib.md5() m.update(bytes(appid+current_time,encoding='utf-8')) new_appid = m.hexdigest()new_new_appid = "%s|%s" %(new_appid,current_time) print(new_new_appid)server端split('|')接收到的字符串,獲取時間戳,和token拼接,做MD5校驗之后,與加密的密文比對;
但是問題又來了,一旦用戶成功的請求被攔截,就可以獲取加密的密文和時間戳,這一串字符串可以直接被server驗證通過;
所以,最終的解決方式是:在server端維護一個列表,一旦成功的用戶請求到來,將其加密的密文加到列表中,下一次請求到來后,先檢查加密的字符串是否在列表中,如果存在,直接返回失敗,如果不存在,并且時間在10s以內,再做后續的操作。需要注意的是,列表維護的信息,是10s(或其他時間段)以內的;如果這個列表存在于redis或者memcache中,可以借助redis和memcache的特性,刪除10s以前的數據,會更簡單;
下面是參考代碼:
?
client side:
#!/usr/bin/env python # _*_ coding:utf-8 _*_ __author__ = "charles"import requests appid = 'asjdhjasdasgdd'import hashlib import time current_time = str(time.time()) m = hashlib.md5() m.update(bytes(appid+current_time,encoding='utf-8')) new_appid = m.hexdigest()new_new_appid = "%s|%s" %(new_appid,current_time) print(new_new_appid)response = requests.get(url='http://127.0.0.1:8080/asset/',# params={'appid',appid},headers = {'appid':new_new_appid}) print(response.text)
server side:
from django.shortcuts import render,HttpResponse# Create your views here.from django.views import View import hashlib import timeclass AssetView(View):#1.時間 2.是否已經存在 3.正向加密def get(self,request,*args,**kwargs):visited = [] #列表需要維護時間,如果使用redis或者memcache就簡單了req_appid = request.META['HTTP_APPID']print(req_appid)APPID = 'asjdhjasdasgdd'v,client_time = req_appid.split('|')current_time = time.time()float_client_time = float(current_time)if current_time - 10 > float_client_time:return HttpResponse('驗證失敗')if req_appid in visited:return HttpResponse('驗證失敗')m = hashlib.md5()m.update(bytes(APPID+client_time,encoding='utf-8'))new_appid = m.hexdigest()if new_appid == v:visited.append(req_appid)return HttpResponse('...')else:return HttpResponse('去你的吧。。。')?
轉載于:https://www.cnblogs.com/cqq-20151202/p/6956878.html
總結
- 上一篇: C# LINQ系列:LINQ to Da
- 下一篇: 《微服务设计》(三)---- 集成