APIインタフェース認証
以前、api方式でサービス側にデータを渡す処理を説明した「簡単なAPIの実現」という文章を書いたことがありますが、この過程で認証機能はなく、誰がどんな内容を送っても一括して受信するという明らかに不安全性があり、この文章は元の基礎の上で、インタフェース認証機能を追加しました.インタフェース認証方式:方式一:クライアント:は、鍵 を定義することによって、鍵暗号化をサービス側 に送信する.
サービス:サービス側は同じ鍵 を定義する.同じ暗号化アルゴリズムにより、 の値が得られる.サービス側が暗号化する値とクライアントから送信された暗号化鍵とを比較する .
欠点:鍵固定不変、暗号化後の値固定不変、露出しやすく、安全性が低い 方式二:クライアント:は、鍵 を定義することによって、鍵を現在のタイムスタンプとともに暗号化し、値 を得る.は、暗号化鍵をタイムスタンプとともにサービス側 に送信する.
サービス:サービス側は同じ鍵 を定義する.現在のサーバ側時間と送信されたクライアント時間を比較し、120 sなどの許容可能な時間範囲を設定する.サーバの現在時刻-送信クライアント>120 sの場合、false に戻ります.は、サービス側の鍵とクライアント時間とを同じ暗号化アルゴリズムを行い、 の値を得る.は、サービス側が暗号化する値とクライアントから送信された暗号化鍵とを比較し、 と一致するか否かを示す.
メリット:暗号化された鍵は毎回異なり、 を解読しにくい.有効時間を設定し、安全性 を増加する.
欠点:クライアント時間とサービス側時間の差は大きくできません.もし大きすぎて認証に失敗したり、問題を調べにくい場合は、同じクロックサーバを使用して同期 を行うことが望ましいです.
コードの説明は次のとおりです.
クライアントコード:
サービス側コード(django):urls.py設定
ビューコード(views.py)
サービス:
欠点:
サービス:
メリット:
欠点:
コードの説明は次のとおりです.
クライアントコード:
#!/usr/bin/env python
#coding:utf8
import json
import platform
import psutil
import urllib,urllib2
import time
import hashlib
from multiprocessing import cpu_count
sys_info={}
sys_info['system'] = []
sys_info['cpu'] = []
sys_info['mem'] = []
sys_info['disk'] = []
sys_info['wip'] = []
sys_info['apikey'] = []
#
system=sys_info['system'].append(platform.uname()[0])
#cpu
cpu_count=sys_info['cpu'].append(cpu_count())
#
mem = psutil.virtual_memory()
mem_info = sys_info['mem'].append(mem.total * 1 / (1024**3))
#
sdiskusage = psutil.disk_usage('/')
disk_info =sys_info['disk'].append(sdiskusage.total * 1 / (1024**3))
# ip
def pub_ip():
url = "http://ip.cip.cc"
wip = urllib2.urlopen(url).readline().rstrip()
return wip
sys_info['wip'].append(pub_ip())
#
def Api_key():
client_key = "ddfd-grgf-dsgf-dgfd" # key
hash_obj = hashlib.md5() # md5 , sha256
time_span = time.time()
hash_obj.update("%s|%f" %(client_key,time_span)) # , update
encryption = hash_obj.hexdigest() #
result = "%s|%f" %(encryption,time_span)
return result
sys_info['apikey'].append(Api_key())
if __name__ == '__main__':
print sys_info
print json.dumps(sys_info,indent=4,ensure_ascii=False)
data = urllib.urlencode(query=sys_info)
print data
respose = urllib.urlopen(url="http://127.0.0.1:8090/serveradd/", data=data)
サービス側コード(django):urls.py設定
url(r'^serveradd/$','app.views.serveradd'),
ビューコード(views.py)
def api_valid(data):
import time,hashlib
server_key = "ddfd-grgf-dsgf-dgfd" # key,
try:
encryption , time_span = data.split("|")
print "------->" ,encryption
print "------->" ,time_span
time_span = float(time_span)
#time.sleep(6) #
now_time = time.time()
if (now_time - time_span) > 5:
print " , "
return False
hash_obj = hashlib.md5() # md5
print "hash_obj------------",hash_obj
hash_obj.update("%s|%f" %(server_key,time_span)) # , update
print hash_obj.hexdigest() #
if hash_obj.hexdigest() == encryption:
return True
else:
print " , ."
return False
except Exception,e:
pass
return False
def api_auth(func):
def wrapper(req):
request_dict = req.POST
api_key = request_dict.get('apikey')
api_key = api_key[2:-2]
print api_key
if not api_key:
return HttpResponse("Unauthorized.")
if not api_valid(api_key):
return HttpResponse("Unauthorized.")
return func(req)
return wrapper
@api_auth
def serveradd(req):
if req.method == 'GET':
print "GET -----error"
elif req.method == 'POST':
print "POST method"
request_dict = req.POST
print request_dict
system = request_dict.get('system')
wip = request_dict.get('wip')
data = {k: v for k, v in request_dict.items()}
host = Host.objects.filter(wip=wip).first()
if not host:
host = Host(**data)
host.save(force_insert=True)
data = {
'msg': 'ok',
'status': 'ok'
}
return HttpResponse(data)
:
1. , :
POST method-------
----['Darwin']----['14.196.121.237']
2. key , , :
1ab7370c45587a9d4d0d1d8f28bd09d7|1477795289.186698
-------> 1ab7370c45587a9d4d0d1d8f28bd09d7
-------> 1477795289.186698
e9d558f11074410464d1769fb2930e81
, 。
3. ( 5s, 6s ), , :
9dc916fbb04c1310cece3aaa5b2d1b7e|1477795521.379039
-------> 9dc916fbb04c1310cece3aaa5b2d1b7e
-------> 1477795521.379039
,