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

时间:2022-12-26 14:34:22

1、认证思路刨析过程

1、请求头去哪里拿?

1、服务器端代码:

def test(request):
print(request)
return HttpResponse('你得到我了')

2、客户端1:

import requests

key = "asdfuasodijfoausfnasdf"

response = requests.get('http://127.0.0.1:8000/api/test.html',headers={'auth_api':key})
print(response.text)

3、服务器截图1:

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

是因为客户端写的格式有问题更改客户端代码如下:

import requests

key = "asdfuasodijfoausfnasdf"

response = requests.get('http://127.0.0.1:8000/api/test.html',headers={'auth-api':auth_header_val})
print(response.text)

4、服务器端截图2:

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

5、案例:

项目需要在http header加上自定义内容, 后台使用Django。 用postman添加header后发送请求, 在request中没有发现自定义的内容,开始怀疑是postman没有成功添加自定义header内容, 于是用python requests包写请求发送, 还是没有发现,  最后去查Django发现了秘密。

Django将所有http header(包括自定义的)的内容都放到了request的META里面了, 这是个标准的python dict, 并且对自定义的内容进行了重命名, 规则如下:

(1) 所有header名大写,将连接符“-”改为下划线“_”

(2) 除CONTENT_TYPE和CONTENT_LENGTH,其它的header名称前加“HTTP_”前缀

请求头去:request.META['HTTP_AUTH_API']里面找

第一关:Django程序发送请求头

服务器端代码:

def test(request):
client_key = request.META.get('HTTP_AUTH_API')
if client_key == key:
return HttpResponse('你得到我了')
else:
return HttpResponse('休想')

客户端代码:

import requests
import time
import hashlib response = requests.get('http://127.0.0.1:8000/api/test.html',headers={'auth-api':key})
print(response.text)

黑客端代码:

import requests
import time
import hashlib response = requests.get('http://127.0.0.1:8000/api/test.html',headers={'auth-api':'asdfuasodijfoausfnasdf'})
print(response.text)

黑客截取成功:

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

2、此方法存在的问题:

要是被黑客截取就很危险

第二关:md5和时间,请求头中的值动态起来

服务器端代码:

def md5(arg):
hs = hashlib.md5()
hs.update(arg.encode('utf-8'))
return hs.hexdigest() key = "asdfuasodijfoausfnasdf" def test(request):
auth_header_val = request.META.get('HTTP_AUTH_API')
# 841770f74ef3b7867d90be37c5b4adfc|1506571253.9937866
client_md5_str, client_ctime = auth_header_val.split('|', maxsplit=1) server_md5_str = md5("%s|%s" % (key, client_ctime,))
if server_md5_str != client_md5_str:
return HttpResponse('你得到我了')
else:
return HttpResponse('休想')

客户端代码:

import requests
import time
import hashlib def md5(arg):
hs = hashlib.md5()
hs.update(arg.encode('utf-8'))
return hs.hexdigest() key = ""
ctime = str(time.time())
new_key = "%s|%s" %(key,ctime,) # asdfuasodijfoausfnasdf|时间戳
md5_str = md5(new_key)
# 6f800b6a11d3f9c08c77ef8f77b2d460, # asdfuasodijfoausfnasdf|时间戳
auth_header_val = "%s|%s" %(md5_str,ctime,) # 6f800b6a11d3f9c08c77ef8f77b2d460|时间戳
print(auth_header_val) response = requests.get('http://127.0.0.1:8000/api/test.html',headers={'auth-api':auth_header_val})
print(response.text)

黑客代码

import requests
import time
import hashlib response = requests.get\
('http://127.0.0.1:8000/api/test.html',headers={'auth-api':'a1c3038f9576429b584ad146d6c4e4e1|1531981662.0696678'})
print(response.text)

正常客户端截图:

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

黑客端截取成功:

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

此方法存在的问题:

第三关:时间 [10s]+加密规则+是否已经存在【10s】

服务器端代码:

def md5(arg):
hs = hashlib.md5()
hs.update(arg.encode('utf-8'))
return hs.hexdigest() key = "asdfuasodijfoausfnasdf"
# redis,Memcache
visited_keys = {
# "841770f74ef3b7867d90be37c5b4adfc":时间, 10
} 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('休想') # 第三关:
if visited_keys.get(client_md5_str):
return HttpResponse('你放弃吧,来晚了') visited_keys[client_md5_str] = client_float_ctime
return func(request,*args,**kwargs) return inner @api_auth
def test(request):
return HttpResponse('正常用户')

客户端代码:

import requests
import time
import hashlib def md5(arg):
hs = hashlib.md5()
hs.update(arg.encode('utf-8'))
return hs.hexdigest() key = "asdfuasodijfoausfnasdf"
ctime = str(time.time())
new_key = "%s|%s" %(key,ctime,) # asdfuasodijfoausfnasdf|时间戳
md5_str = md5(new_key)
# 6f800b6a11d3f9c08c77ef8f77b2d460, # asdfuasodijfoausfnasdf|时间戳
auth_header_val = "%s|%s" %(md5_str,ctime,) # 6f800b6a11d3f9c08c77ef8f77b2d460|时间戳
print(auth_header_val)

黑客端代码:

import requests
import time
import hashlib response = requests.get('http://127.0.0.1:8000/api/test.html',
headers={'auth-api':"0d89c03e8237263a2e24ecc3e82e2bf|1531983245.4202634"})
print(response.text)

正常客户端截图:

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

黑客端截图:第三关超时

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

黑客端截图:第一关超时

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

解决方案:
1. 时间 [10s]
2. 加密规则
3. 是否已经存在【10s】

5、客户端目录结构:

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

1、client.py

import requests
import time
import hashlib def md5(arg):
hs = hashlib.md5()
hs.update(arg.encode('utf-8'))
return hs.hexdigest() key = "asdfuasodijfoausfnasdf"
ctime = str(time.time())
new_key = "%s|%s" %(key,ctime,) # asdfuasodijfoausfnasdf|时间戳
md5_str = md5(new_key)
# 6f800b6a11d3f9c08c77ef8f77b2d460, # asdfuasodijfoausfnasdf|时间戳
auth_header_val = "%s|%s" %(md5_str,ctime,) # 6f800b6a11d3f9c08c77ef8f77b2d460|时间戳
print(auth_header_val) response = requests.get('http://127.0.0.1:8000/api/test.html',headers={'auth-api':auth_header_val})
print(response.text)

2、harker.py

import requests
import time
import hashlib response = requests.get('http://127.0.0.1:8000/api/test.html',
headers={'auth-api':"387f764fc53eb316f148778ba2829b34|1506572694.6821892"})
print(response.text)

6、服务器端目录结构:

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

1、views.py

import json
from django.shortcuts import render,HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from repository import models
from .plugins import PluginManger
from django.db.models import Q
from datetime import date
import hashlib
import time # ############################################## API验证示例 ##############################################
def md5(arg):
hs = hashlib.md5()
hs.update(arg.encode('utf-8'))
return hs.hexdigest() key = "asdfuasodijfoausfnasdf"
# redis,Memcache
visited_keys = {
# "841770f74ef3b7867d90be37c5b4adfc":时间, 10
} 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('休想') # 第三关:
if visited_keys.get(client_md5_str):
return HttpResponse('你放弃吧,来晚了') visited_keys[client_md5_str] = client_float_ctime
return func(request,*args,**kwargs) return inner @api_auth
def test(request):
return HttpResponse('正常用户') 

2、urls.py

添加:url(r'^test.html$', views.test)作为测试

from django.conf.urls import url
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^server.html$', views.server),
url(r'^test.html$', views.test),
]