API验证说明

API验证:

    a. 发令牌: 静态
PS: 隐患 key被别人获取
b. 动态令牌
PS: (问题越严重)用户生成的每个令牌被黑客获取到,都会破解
c. 高级版本
PS: 黑客网速快,会窃取, so要对数据加密
d. 终极版本 特点:
为什么要用API ?
- 数据在传输过程中,保证数据安全
你是如何设计的 ?
- Tornado 中的加密Cookie类似
- 创建动态key md5(key + time)|time (Tornado中也是这么做)
- 限制
- 第一关: 时间
- 第二关: 算法规则
- 第三关: 已访问的记录
PS: 黑客网速快,会窃取, so要对数据加密

1、发令牌: 静态(服务器、客户端有相同的静态key)

###客户端
import requests key = "asdfasdfasdfasdf098712sdfs" response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':key})
print(response.text)
###服务端

def api_check(request):
if request.method == "GET":
#################静态################
server_key = "adsfasdfzxcvzw241wdsaddsfsdf" # 应放在settings
client_key = request.META.get("HTTP_OPENKEY") # META里的Openkey字段会自动修改,需提前看META里的字段 if server_key != client_key:
return HttpResponse("key错误,你是非法用户") return HttpResponse("欢迎光临")
2、动态令牌
### 客户端
import requests
import time
import hashlib ctime = time.time()
key = "adsfasdfzxcvzw241wdsaddsfsdf"
new_key = "%s|%s" % (key,ctime,) m = hashlib.md5()
m.update(bytes(new_key,encoding="utf-8"))
md5_key = m.hexdigest() # key进行hash new_time_key = "%s|%s" % (md5_key,ctime,) response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={"openkey":new_time_key})
print(response.text)
#### 服务端
def api_check(request):
if request.method == "GET":
server_key = "adsfasdfzxcvzw241wdsaddsfsdf" # 应放在settings client_md5_time_key = request.META.get("HTTP_OPENKEY")
client_md5_key, client_ctime = client_md5_time_key.split("|") temp = "%s|%s" % (server_key, client_ctime)
m = hashlib.md5()
m.update(bytes(temp, encoding='utf-8'))
server_md5_key = m.hexdigest() if server_md5_key != client_md5_key:
return HttpResponse("验证失败") return HttpResponse("欢迎光临,访问成功")

3、高级版本

(1)、时间限制,超过自定义时间(自定义10s)不让访问

(2)、hash限制,比对server和client的hash值

(3)、记录自定义时间内已访问的hash_key,禁止重复访问

### 客户端
import requests
import time
import hashlib ctime = time.time()
key = "adsfasdfzxcvzw241wdsaddsfsdf"
new_key = "%s|%s" % (key,ctime,) m = hashlib.md5()
m.update(bytes(new_key,encoding="utf-8"))
md5_key = m.hexdigest() # key进行hash new_time_key = "%s|%s" % (md5_key,ctime,) response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={"openkey":new_time_key})
print(response.text)
### 服务端(装饰器版本)

api_key_record = {}  # 创建全局的字段,记录自定义时间内已访问的hash_key
def API_check(func):
def wrapper(request,*args,**kwarg):
if request.method == "GET":
import hashlib
# ####################API认证##################
client_md5_time_key = request.META.get("HTTP_OPENKEY")
client_md5_key, client_ctime = client_md5_time_key.split("|")
client_ctime = float(client_ctime)
server_time = time.time()
# 第一关
if server_time - client_ctime > 10:
return HttpResponse("【第一关】时间有点长") # 第二关
tmp = "%s|%s" % (settings.AUTH_KEY, str(client_ctime))
m = hashlib.md5()
m.update(bytes(tmp, encoding="utf-8"))
server_md5_key = m.hexdigest()
if server_md5_key != client_md5_key:
return HttpResponse("【第二关】规则不正确,验证码错误") for k in list(api_key_record.keys()):
v = api_key_record[k]
if server_time > v:
api_key_record.pop(k) # 第三关
if client_md5_time_key in api_key_record:
return HttpResponse("【第三关】有人已经来过了")
else:
api_key_record[client_md5_time_key] = client_ctime + 10 # ####################API认证##################
ret = func(request,*args,**kwarg)
return ret
return wrapper @API_check
def asset(request):
。。。。。。
# 主函数

4、终极版本(加密)

from Crypto.Cipher import AES
from lib.conf.config import settings
def encrypt(message):
"""
数据加密
:param message:
:return:
"""
key = settings.DATA_KEY
cipher = AES.new(key, AES.MODE_CBC, key)
ba_data = bytearray(message,encoding='utf-8')
v1 = len(ba_data)
v2 = v1 % 16
if v2 == 0:
v3 = 16
else:
v3 = 16 - v2
for i in range(v3):
ba_data.append(v3)
final_data = ba_data.decode('utf-8')
msg = cipher.encrypt(final_data) # 要加密的字符串,必须是16个字节或16个字节的倍数
return msg def decrypt(msg):
"""
数据解密
:param message:
:return:
"""
from Crypto.Cipher import AES
key = settings.DATA_KEY
cipher = AES.new(key, AES.MODE_CBC, key)
result = cipher.decrypt(msg) # result = b'\xe8\xa6\x81\xe5\x8a\xa0\xe5\xaf\x86\xe5\x8a\xa0\xe5\xaf\x86\xe5\x8a\xa0sdfsd\t\t\t\t\t\t\t\t\t'
data = result[0:-result[-1]]
return str(data,encoding='utf-8') def auth(): # hash(key+时间)
"""
API验证
:return:
"""
import time
import requests
import hashlib ctime = time.time()
key = "asdfasdfasdfasdf098712sdfs"
new_key = "%s|%s" %(key,ctime,) m = hashlib.md5()
m.update(bytes(new_key,encoding='utf-8')) #里面是字节数据
md5_key = m.hexdigest() #返回值是字符窜类型 md5_time_key = "%s|%s" %(md5_key,ctime) return md5_time_key

lib/utils.py

from Crypto.Cipher import AES
import requests
import json
from lib.utils import encrypt
from lib.utils import auth #对数据加密字典
v1 = encrypt(json.dumps({"k1":"v1"})) #获取的是加密后的字节
print(v1) response = requests.post(
url="http://127.0.0.1:8000/api/asset.html",
headers={'OpenKey':auth(),'content-type':'application/json'},
data=v1
) print(response.text)

客户端

import json
import hashlib
from django.shortcuts import render,HttpResponse
from repository import models
from django.conf import settings
from api.service import PluginManager
import time
import json
from Crypto.Cipher import AES api_key_record ={
"76942d662d98ebe3b920a7b791bf5040|1501510243.92804":1501510243.92804,
} def decrypt(msg):
key = b'dfdsdfsasdfdsdfs'
cipher = AES.new(key, AES.MODE_CBC, key)
result = cipher.decrypt(msg) # 把加密后的字节解密成不加密的字节
data = result[0:-result[-1]]
return str(data, encoding='utf-8') def outer(func):
def wrapper(request):
client_md5_time_key = request.META.get("HTTP_OPENKEY") client_md5_key, client_ctime = client_md5_time_key.split("|")
client_ctime = float(client_ctime)
server_ctime = time.time() # 第一关 时间关
if server_ctime - client_ctime > 30:
return HttpResponse("第一关 小伙子,别虎我,太长了") # 第二关 客户端时间和服务端key加密和 客户端的密钥对比
temp = "%s|%s" % (settings.AUTH_KEY, client_ctime)
m = hashlib.md5()
m.update(bytes(temp, encoding='utf-8'))
server_md5_key = m.hexdigest()
if server_md5_key != client_md5_key:
return HttpResponse("第二关 规则正确") # 以后基于memcache,目前先写入内存删除超过10s的值
for k in list(api_key_record.keys()):
v = api_key_record[k]
if server_ctime > v:
del api_key_record[k] # 第三关 判断字典里是否有之前访问的key,如果有不通过,没有加入字典
if client_md5_time_key in api_key_record:
return HttpResponse("第三关 已经有人来过了")
else:
api_key_record[client_md5_time_key] = client_ctime + 10
obj = func(request)
return obj return wrapper @outer
def asset(request): if request.method == 'GET':
ys = '重要的不能被闲杂人等看的数据'
return HttpResponse(ys) elif request.method == 'POST': server_info = decrypt(request.body)
server_info = json.loads(server_info) # # 新资产信息
# server_info = json.loads(request.body.decode('utf-8'))
hostname = server_info['basic']['data']['hostname']
# 老资产信息
server_obj = models.Server.objects.filter(hostname=hostname).first()
if not server_obj:
return HttpResponse('当前主机名在资产中未录入') PluginManager(server_info,server_obj,hostname).exec_plugin() return HttpResponse("...")

服务端

API验证的更多相关文章

  1. python API验证

    API验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 API验证:     a. 发令牌: 静态         PS: 隐患 key ...

  2. API验证及AES加密

    API验证 API验证: a. 发令牌: 静态 PS: 隐患 key被别人获取 b. 动态令牌 PS: (问题越严重)用户生成的每个令牌被黑客获取到,都会破解 c. 高级版本 PS: 黑客网速快,会窃 ...

  3. CMDB服务器管理系统【s5day90】:API验证

    1.认证思路刨析过程 1.请求头去哪里拿? 1.服务器端代码: def test(request): print(request) return HttpResponse('你得到我了') 2.客户端 ...

  4. API验证插件

    前言 如果在访问某WebAPI过程中request信息被他人截获,若是get请求获取数据还好,如果是post提交数据,势必威胁数据安全,所以对于一个对安全性要求较高的API来说,对每个请求做身份验证显 ...

  5. 基于 JWT-Auth 实现 API 验证

    基于 JWT-Auth 实现 API 验证 如果想要了解其生成Token的算法原理,请自行查阅相关资料 需要提及的几点: 使用session存在的问题: session和cookie是为了解决http ...

  6. CMDB 数据加密 最终整合API验证+AES数据加密

    当CMDB运行在内网的时候,经过API验证的三关是没有问题的,但是如果运行在外网,有一个问题是,黑客截取后的访问速度比客户端快的时候还会造成数据泄露.为了解决这个问题,就要对数据进行加密 RSA加密 ...

  7. CMDB API验证

    CMDB API验证 为什么做API验证 API验证是防止数据在传输的过程中,保证数据不被篡改 如何设计的API验证 灵感来源于Torando中加密Cookie的源码,主要是生成加密的随机字符串. M ...

  8. Django学习手册 - 基于requests API验证(二)

    原理分析: API接口验证 1.一个认证的key server端 和 client端都必须有这么一个认证key. 2.认证登录的时间限定 3.保存已验证的信息,在以后的验证不能再次登录 client ...

  9. Django学习手册 - 基于requests API验证(一)

    验证需要知道requests提交数据的几种方式: GET 方式: # get 方式,传递数值可以直接通过url传递:(服务端接受 GET) requests.get(url='http://127.0 ...

随机推荐

  1. 【vue】npm run mock & npm run dev 无法同时运行的解决

    [关于系统,没注明的都是windows系统,若以后用的是mac系统则会另外备注] 当项目数据是通过mock搭建而成(参照:[vue]本地开发mock数据支持)时,运行mock服务器和项目的命令 就参照 ...

  2. 底部带突出按钮的tabbar

    #import "ViewController.h" #import "FirstViewController.h" #import "SecondV ...

  3. Yii2 的安装及简单使用

    前段时间第一次使用Yii2框架,碰到了一些问题,这里记录一下. Yii2安装:通过composer安装 1.首先要安装composer,我在另外一篇博客中介绍了如何在Windows下安装compose ...

  4. Weblogic申请和配置SSL证书

    一. 概述 SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协 ...

  5. 基于BM3803处理器平台的PCI软硬件调试问题汇总(持续更新中)

    一:相关基本配置: FPGA:  XILINX XC5VFX130T-1FFG1738 PCI接口部分使用XILINX提供的pci32_v4_8硬核:PCI控制器由FPGA逻辑实现,主要完成PCI设备 ...

  6. ISE14.7使用教程(一个完整工程的建立)

    FPGA公司主要是两个Xilinx和Altera(现intel PSG),我们目前用的ISE是Xilinx的开发套件,现在ISE更新到14.7已经不更新了,换成了另一款开发套件Vivado,也是Xil ...

  7. 获取当前页面的所有链接的四种方法对比(python 爬虫)

    ''' 得到当前页面所有连接 ''' import requests import re from bs4 import BeautifulSoup from lxml import etree fr ...

  8. Deep Learning Tutorial 李宏毅(一)深度学习介绍

    大纲 深度学习介绍 深度学习训练的技巧 神经网络的变体 展望 深度学习介绍 深度学习介绍 深度学习属于机器学习的一种.介绍深度学习之前,我们先大致了解一下机器学习. 机器学习,拿监督学习为例,其本质上 ...

  9. 33 -jQuery 属性操作,文档操作(未完成)

  10. 2653: middle

    2653: middle 链接 分析: 二分答案+主席树. 对于中位数的经典做法,就是二分一个数,将小于的变成-1,大于等于的变成+1,那么如果sum>=0(因为+1包括等于),L=mid+1, ...