CMDB服務器管理系統【s5day90】:API驗證

一、認證思路刨析過程

一、請求頭去哪裏拿?

一、服務器端代碼:html

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

二、客戶端1:python

import requests

key = "asdfuasodijfoausfnasdf"

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

三、服務器截圖1:redis

是由於客戶端寫的格式有問題更改客戶端代碼以下:django

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)

四、服務器端截圖2:json

 五、案例:api

項目須要在http header加上自定義內容, 後臺使用Django。 用postman添加header後發送請求, 在request中沒有發現自定義的內容,開始懷疑是postman沒有成功添加自定義header內容, 因而用python requests包寫請求發送, 仍是沒有發現,  最後去查Django發現了祕密。 服務器

Django將全部http header(包括自定義的)的內容都放到了request的META裏面了, 這是個標準的python dict, 而且對自定義的內容進行了重命名, 規則以下:post

(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)

黑客截取成功:

二、此方法存在的問題:

要是被黑客截取就很危險

第二關: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】

五、客戶端目錄結構:

一、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)

二、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)

六、服務器端目錄結構:

 一、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('正經常使用戶') 

二、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),
]
相關文章
相關標籤/搜索