背景需求
写了一个牛逼的接口
def server_info(request):
result = {"isSuccess": True, "message": 3}
return HttpResponse(json.dumps(result))
突然有一天这个接口变成了超级牛逼的接口,需要被其它系统调用了,安全的需求出现了。
加密原理
1 首先双方约定一个 TOKEN 。这个TOKEN说白了就是一长串没有规则的数字 + 字母 + 特殊字符的组合。
2 明文传输肯定不行啊,选了个主流的sha1,但是每次都传一样的加密信息早晚是要被别人搞啊。
要不断变化才行,时间戳这个时候出场了,主角来了: sha1(token + timestamp)|timestamp. (|timestamp 是干嘛用的 有小伙伴猜到了么?)
用户传 sha1(token + 用户的timestamp)|用户的timestamp 这个信息给我,我拿到数据后从 “|”切割开来备用,我也来加密一下sha1(token + 用户的timestamp)。用我加密的数据对比一下”|”前面加密的数据就知道 用户传过来的token是不是你和用户约定好的那个了。
3 为了更加安全 我们还设置了过期时间。
代码实现
写了一个那么牛逼的接口代码 有办法不去修改接口代码就实现接口加密呢? 然后有啦,装饰器这个时候派上用场了。
装饰器代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from django.shortcuts import HttpResponse
from api import Securty
def api_auth(func):
def wrapper(request):
securty_key = request.GET.get('securtykey',None)
if not securty_key:
return HttpResponse('Unauthorized')
if not Securty.auth_api_vaild(securty_key):
return HttpResponse('Unauthorized')
return func(request)
return wrapper
加密逻辑实现
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import hashlib
WEBAPI_TOKEN = "**********************"
expires_time = 180
def auth_api_vaild(data):
try:
encryption,time_span = data.split('|')
time_span = float(time_span)
if (time.time() - time_span) > expires_time:
return False
str_key = ('%s|%f' % (WEBAPI_TOKEN, time_span)).encode('utf-8')
hash_obj = hashlib.sha1()
hash_obj.update(str_key)
if hash_obj.hexdigest() == encryption:
return True
else:
return False
except Exception as e:
print(e)
return False
创建测试api_key
import hashlib
import time
WEBAPI_TOKEN = "****************"
def create_api_key():
hash_obj = hashlib.sha1()
key = WEBAPI_TOKEN
time_span = time.time()
str_key = ('%s|%f' %(key,time_span)).encode('utf-8')
hash_obj.update(str_key)
encryption = hash_obj.hexdigest()
result = '%s|%f'%(encryption,time_span)
return result
验证结果
先用 create_api_key函数 跑一个测试用的 api_key
**************ceb8eaf0da77c7f98f121878|1482846167.177168