Python API简单验证
前言
因为CMDB内部的需求,需要一个API进行数据传输,用来传递需要抓取的服务端信息信息给抓取的autoclient,autoclient抓取好之后再通过API传输到服务器,保存到数据库。但是为了防止恶意的API访问,需要做一个验证。
设想一
可以在客户端跟服务端都规定好一串随机字符串做验证,只有当带着这串验证的请求发送过来的时候,才让其进行访问。
如果学过了爬虫,大家很容易就发现,这串随机字符串在浏览器里面是可以监听的,多观察几次总是会发现的。而且无论通过如何的方式,只要暴露在外面,都是会被察觉的。此时,就需要对其进行加密。
设想二
既然随机字符串在web传输中是明文状态,那我们试着将其转换成密文的,转换下思路,如果每次的请求都是随机字符串配合一串一直变动的值进行md5加密,此时,产生的验证字符串也应该变成动态密文。用什么做动态字符串来配合约定好的字符串进行md5加密呢?既然是动态的,时间戳,是最好的选择。
此时一切看着都很完美,但是,忽略了一点,无论是不是加密的字符串,http请求的时候都是可以监听到的,所以即使加密,即使不知道怎么加密的,依旧可以直接拿着这串字符串直接进行验证访问。尴尬。。。
设想三
其实上面的设想二已经做到了动态,思路上只要改一点就立刻变成可行的了。在http请求的时候,即使是在相当糟糕的网络环境里,也不会需要发送非常长的时间,因此,卡住时间便可以实现。
在拿到client的时间戳是,服务器段只需要跟当前时间戳进行比对,如果时间间隔小于10秒就当作正常访问。就可以了。
上面的设计思路完美的解决了动态的问题,此时不免还有疑问,如果真的会在10s内盗取到字符串直接访问呢?
完善思路
基于上面的问题,可以再多加异步验证,写一个列表,访问过的字符串都放在列表里,后面的访问都跟此列表比对下,如果在此列表内,就拒绝访问。
如上的设计思路就可以解决问题。
优化
最后的设计思路肯定能解决问题,但是也存在一个问题,就是,随着时间进度的推移,访问列表一定会越来越大,始终是不友好的一点。肯定需要给字符串设计一个超时时间。
visited_list = ['28g12b12128912e2kj|127381237812391', '829312g12be120e102ej12je91|12312984123123',....]
如果以上述的方式取跟系统时间比较当然是一件很费事的工作,占用很多的IO,可以使用redis来轻松实现这个功能。
CBV通过此类装饰方式实现验证
验证代码
def api_auth_method(request):
auth_key = request.META.get('HTTP_AUTH_KEY')
if not auth_key:
return False
sp = auth_key.split('|')
if len(sp) != 2:
return False
encrypt, timestamp = sp
timestamp = float(timestamp)
limit_timestamp = time.time() - ASSET_AUTH_TIME
print(limit_timestamp, timestamp)
if limit_timestamp > timestamp:
return False
ha = hashlib.md5(ASSET_AUTH_KEY.encode('utf-8'))
ha.update(bytes("%s|%f" % (ASSET_AUTH_KEY, timestamp), encoding='utf-8'))
result = ha.hexdigest()
print(result, encrypt)
if encrypt != result:
return False exist = False
del_keys = []
for k, v in enumerate(ENCRYPT_LIST):
print(k, v)
m = v['time']
n = v['encrypt']
if m < limit_timestamp:
del_keys.append(k)
continue
if n == encrypt:
exist = True
for k in del_keys:
del ENCRYPT_LIST[k] if exist:
return False
ENCRYPT_LIST.append({'encrypt': encrypt, 'time': timestamp})
return True def api_auth(func):
def inner(request, *args, **kwargs):
if not api_auth_method(request):
return JsonResponse({'code': 1001, 'message': 'API授权失败'}, json_dumps_params={'ensure_ascii': False})
return func(request, *args, **kwargs) return inner
auth
Python API简单验证的更多相关文章
- web api简单验证实现办法
需要使用WEBAPI,但是有验证问题没解决.后来参考网上文章做了一下DEMO 思路: 就是根据用户的账号在服务端加密一个字符串,然后返回给用户端. 具体: 一个用户编号用于唯一身份识别,密码,一个密钥 ...
- 02 . SaltStack高级用法(Python API)
Python API简单使用 第一条命令 /usr/bin/salt默认使用的接口是LocalClient,该接口只能在salt master上使用 >>> import salt. ...
- Python实现简单登陆验证(文件操作)
利用python编写一个简单的登陆验证 代码主要功能: 利用Python实现简单的登陆验证,代码主要有两个部分组成: 第一部分:登陆页面,作用是实现用户名和密码的输入 利用两个输入函数input()来 ...
- python练习笔记——编写一个装饰器,模拟登录的简单验证
编写一个装饰器,模拟登录的简单验证(至验证用户名和密码是否正确) 如果用户名为 root 密码为 123则正确,否则不正确.如果验证不通过则不执行被修饰函数 #编写一个装饰器,模拟登录的简单验证 #只 ...
- Python API:openstack
OpenStack 是一个越来越流行的.用于部署基础架构即服务 (IaaS) 云的开源解决方案.OpenStack 附带了一个仪表板 Web 应用程序,非常适合执行手动任务,比如启动单个虚拟机 (VM ...
- Python Api接口自动化测试框架 excel篇
工作原理: 测试用例在excel上编辑,使用第三方库xlrd,读取表格sheet和内容,sheetName对应模块名,Jenkins集成服务发现服务moduleName查找对应表单,运用第三方库req ...
- 如何在 Apache Flink 中使用 Python API?
本文根据 Apache Flink 系列直播课程整理而成,由 Apache Flink PMC,阿里巴巴高级技术专家 孙金城 分享.重点为大家介绍 Flink Python API 的现状及未来规划, ...
- Python爬虫简单实现CSDN博客文章标题列表
Python爬虫简单实现CSDN博客文章标题列表 操作步骤: 分析接口,怎么获取数据? 模拟接口,尝试提取数据 封装接口函数,实现函数调用. 1.分析接口 打开Chrome浏览器,开启开发者工具(F1 ...
- Openstack python api 学习文档 api创建虚拟机
Openstack python api 学习文档 转载请注明http://www.cnblogs.com/juandx/p/4953191.html 因为需要学习使用api接口调用openstack ...
随机推荐
- 第二篇-ubuntu18.04下怎么制作GIF动画
一.在桌面打开终端 二.接着通过apt安装byzanz.sudo apt-get install byzanz 三.安装完成后在终端执行“xwininfo”.xwininfo 四.然后鼠标会变成“+” ...
- pytest 8 参数化parametrize
pytest.mark.parametrize装饰器可以实现用例参数化 1.以下是一个实现检查一定的输入和期望输出测试功能的典型例子 import pytest @pytest.mark.parame ...
- java的集合
Collection: 1.list ArrayList.Vector.LinkedList ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构. Vector是 ...
- shell之case
在shell变成中,case语句是if语句的一种扩展,将if中的判断语句,展开,同一个变量,对应多个可能的值时,执行不同的操作.具体句型如下: case "变量" in value ...
- scrapy中css选择器初识
由于最近做图片爬取项目,涉及到网页中图片信息的选择,所以边做边学了点皮毛,有自己的心得 百度图库是ajax加载的,所以解析json数据即可 hjsons = json.loads(response.b ...
- STM32 ------ 串口 数据位长度 和 奇偶校验位
USART_InitStructure.USART_WordLength 的值是数据位长度+一个奇偶校验位(如果无奇偶校验则不加一)
- Calendar 类 案例 和 闰年的计算
Calendar 类 是一个抽象类 getInstance()直接返回子类对象 直接调用 主要方法:get set add 代码如下: package cn.lijun.demo; import ja ...
- CentOS Bash 命令补全增强软件包 bash-completion
引言 之前安装的 CentOS 7 是最小化安装,在使用 systemctl 命令进行服务的管理时,经常手动输入相关服务名.如果对一个服务名称不熟悉,这样可以迫使我们记住它,但如果对一个服务名已经很熟 ...
- CEdit编辑框字体和背景设置
CEdit编辑框字体和背景设置注意事项:当CEdit为“disable”时,设置编辑框的字体和背景会没有效果.解决方案:将CEdit的Style设置为“readonly”,这样设置就能生效了,同时也能 ...
- python对象-多态
调用不同的子类将会产生不同的行为,而无须明确知道这个子类实际上是什么. 比如,在一个可以播放音频文件的程序中,媒体播放器可能需要加载一个AudioFile对象然后play它,我们把一个play()的方 ...