标签:客户 存在 请求 限制 auth ons 服务端 返回 区间
本次API验证是基于Tornado源码中COOKIE的设置,设置的安全访问机制。具体代码如下:
我们的客户端访问使用Py‘t‘hon中的requests模块模拟
import requests
import time
import hashlib
response = requests.get(‘http://127.0.0.1:8000/api/test.html‘,
headers={‘auth-api‘:"xxxxxxxxxxxxxxxxxxx"})
print(response.text)、
其中headers的内容是我们在发送访问请求时携带的请求头信息。
①:为了安全我们首先想到的是在我们的请求头中添加动态信息,来区分我们每一次的访问,那么拿什么来区分呢?
对,我们非常容易想到的就是时间了,我们知道python的时间戳是无时无刻不在刷新的。
那么我们可以在请求头里附加我们访问时的时间戳,而服务器也在收到请求时生成自己的时间戳,如果两者之间的时间间隔超过一定区间,就返回错误信息,从而达到禁止访问的效果。
但是,问题显而易见!只要我在拿到用户第一次访问的请求时,不是那么太晚的去执行我的第二次第三次访问,那么访问依然有效。
②:针对上述情况,我们可以这样设计:
将我们发送的时间戳前边附加一段和服务端约定的字符串,而在我们发送的时候客户端就会把字符串和时间戳组合而成的新字符串按照hash算法计算出hash值,在我们发送的时间就把计
算出的hash值和时间戳用管道符分割一并发送给服务端,服务端在接收的时候通过request.META[‘请求头里的key‘]提取客户端发来的请求头信息,通过分割把hash值和时间字符串拿到
再去利用客户端发来的时间戳和约定好的字符串去hash计算自己的hash值,再去校验是否和客户端发来的信息一致,如果不一致就返回错误页面,否则就正常访问。
这时,一切看起来都是那么的美好,但是,这样就安全了嘛?
如果I am a kacker, I can get your all message.
你要知道,客户端的发送信息都在我的采集范围内,不管你是什么算法,我只知道,这时我用你的发送请求去访问,没毛病,可以用。
③:
针对第二种情况,我们又想到了新的解决办法:
如果我的服务端设置有一个访问过的列表呢?
如果你每一次的访问都存在我的列表中呢?
当你第一次访问,使用了上述的hash检验,并且访问成功,那么恭喜你,你已经成功进入我的列表。
接下来不管你是谁,你拿到了别人的访问信息来访问我,对不起,no more chance.
只要我在①的时间基础上,定期清空,这样我的列表就不会无限增长,而且我是拒绝二次访问的。
具体服务端实现代码如下:
def api_auth(func):
def inner(request,*args,**kwargs):
server_float_ctime = time.time()
auth_header_val = request.META.get(‘HTTP_AUTH_API‘)
# 841770f74ef3b7867d90be37c5b4adfc|1506571253.9937866
client_md5_str, client_ctime = auth_header_val.split(‘|‘, maxsplit=1)
client_float_ctime = float(client_ctime)
# 第一关
if (client_float_ctime + 20) < server_float_ctime:
return HttpResponse(‘超时访问,这一关是时间限制‘)
# 第二关:
server_md5_str = md5("%s|%s" % (key, client_ctime,))
if server_md5_str != client_md5_str:
return HttpResponse(‘hash计算时间戳,第二层限制‘)
# 第三关:
if visited_keys.get(client_md5_str):
return HttpResponse(‘列表监测,对二次访问说拜拜‘)
visited_keys[client_md5_str] = client_float_ctime
return func(request,*args,**kwargs)
return inner
标签:客户 存在 请求 限制 auth ons 服务端 返回 区间
原文地址:http://www.cnblogs.com/575dsj/p/7620208.html