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. PATtest1.3:最大子列和

    题目源于:https://pintia.cn/problem-sets/16/problems/663 题目要求:输入一个数列,求其最大子列和. 问题反馈:1.部分C++代码不是很熟练 2.没有仔细读 ...

  2. jenkins -Djava.awt.headless=true Linux下java.awt.HeadlessException的解决办法

    修改 linux  apache-tomcat-7.0.56/bin \catalina.sh文件 在所有类似以下代码大约有七八处具体自己去看:    "$_RUNJAVA" $J ...

  3. 流程一直处于Running状态,应该怎么停止?

    流程一直处于Running状态,应该怎么停止? 概述 我们有遇到这种情况:可能由于某些原因,流程发起后一直处于Running状态,然后我们想Stop掉这些出问题的流程,这个时候你在Workspace里 ...

  4. linux文件系统初始化过程(2)---挂载rootfs文件系统

    一.目的 本文主要讲述linux3.10文件系统初始化过程的第一阶段:挂载rootfs文件系统. rootfs是基于内存的文件系统,所有操作都在内存中完成:也没有实际的存储设备,所以不需要设备驱动程序 ...

  5. Spring的简单应用与基本原理

    一:重要概念理解 Spring很简单,一定不要想得太复杂,只是有些东西很拗口而已 1:IOC(控制反转) 概念:利用反射的原理将对象创建的权利交给了Spring,Spring在运行的时候根据配置文件( ...

  6. SharePoint document 右键菜单和【...】菜单不一致的解决办法

    [问题]在sharepoint 2016环境中,当用户只有read权限,访问文档库,会发现文档的右键菜单和[…]菜单的内如是不一致的,而更高权限用户都是一致的. [分析]这个跟微软询问过,是个bug, ...

  7. iOS蓝牙开发(4.0)详解

    最近由于项目需要, 一直在研究蓝牙4.0,在这儿分享给大家, 望共同进步. 一.关于蓝牙开发的一些重要的理论概念: 1.当前ios中开发蓝牙所运用的系统库是<CoreBluetooth/Core ...

  8. java常用API之Date类

    Date类: 类 Date 表示特定的瞬间,精确到毫秒. 毫秒概念:1000毫秒=1秒 毫秒的0点: System.currentTimeMillis()  返回值long类型参数   用于获取当前日 ...

  9. 理解C++类的继承方式(小白)

    基类里的 public(大人) protect(青年) private(小孩) 在通过继承时  继承方式public(我是大人咯) protect(我是青少年) private(我系小孩纸啦) &qu ...

  10. WebGl 多缓冲区传递颜色和坐标(矩形)

    效果: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...