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

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:

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

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:

 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)

黑客截取成功:

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)

正常客户端截图:

黑客端截取成功:

此方法存在的问题:

 

第三关:时间 [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)

正常客户端截图:

黑客端截图:第三关超时

黑客端截图:第一关超时

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

5、客户端目录结构:

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、服务器端目录结构:

 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),
]

  

 

posted @ 2018-07-19 10:07  活的潇洒80  阅读(365)  评论(0编辑  收藏  举报