1.1 api认证原理介绍

  1、api认证原理:客户端生成秘钥

      1) 客户端与服务器端有一个相同的字符串作为auth_key
      2) 客户端使用encryption="auth_key|time.time()"用auth_key和客户端时间生成md5秘钥
      3) 客户端将"encryption|time.time()" 将生成的秘钥和发送请求的时间一起发送给服务器

  2、api认证原理:服务器验证秘钥三步曲

      1、时间验证: 如果请求到达服务器端时间距离客户端发送请求的时间大于2秒,验证失败
      2、是否存在: 这个秘钥第一次过来时会加入列表中,如果已经在列表中证明已经来过,验证失败
      3、秘钥正确: 只有前两关都通过,在通过服务器的auth_key与客户端发送的时间生成秘钥看是否相等

1.2 api认证插件使用

  1、测试API认证插件步骤

      1、创建任意django项目,如ApiAuth,无需指定静态文件等,只需创建app01
      2、在app01中使用CBV创建AssetView视图函数处理get和post请求,并重写dispatch方法,不使用csrf规则
      3、在app01同级目录下创建utils目录,并创建认证文件auth.py
      4、在AssetView的get和post函数中使用自己定义的@method_decorator(auth.api_auth)进行api认证
      5、客户端访问时只用使用服务器端指定的字符串,和发送请求的时间生成秘钥,验证通过才能访问

  2、测试代码

import time
import hashlib
from django.http import JsonResponse ASSET_AUTH_KEY = '299095cc-1330-11e5-b06a-a45e60bec08b'
ASSET_AUTH_HEADER_NAME = 'HTTP_AUTH_KEY'
ASSET_AUTH_TIME = 2 ENCRYPT_LIST = [
# {'time': 1516180308.850576, 'encrypt': '25bd4a6454329e7633b4db5c810c44ac'}
] def api_auth_method(request):
# 获取客户端header中传入的验证字符串:{'auth-key': '7b01e466ca23c9a3fb8c3a12b0214635|1516179535.832950'}
auth_key = request.META.get('HTTP_AUTH_KEY')
if not auth_key:
return False
sp = auth_key.split('|')
if len(sp) != 2:
return False
encrypt, timestamp = sp # encrypt = 客户端发送时间 + 授权字符串 的md5值
# timestamp 是客户端发送的时间
timestamp = float(timestamp)
limit_timestamp = time.time() - ASSET_AUTH_TIME if limit_timestamp > timestamp: # 如果当前时间比请求时间的差大于2 秒(验证失败)
return False
ha = hashlib.md5(ASSET_AUTH_KEY.encode('utf-8'))
# 授权字符串 + 客户端发送请求那一刻时间 的md5值与客户端发送的值是否相等
ha.update(bytes("%s|%f" % (ASSET_AUTH_KEY, timestamp), encoding='utf-8'))
result = ha.hexdigest()
if encrypt != result:
return False exist = False
del_keys = []
for k, v in enumerate(ENCRYPT_LIST):
# v = {'time': 1516180308.850576, 'encrypt': '25bd4a6454329e7633b4db5c810c44ac'}
m = v['time']
n = v['encrypt']
if m < limit_timestamp: # 时间已过期
del_keys.append(k) # 将ENCRYPT_LIST列表中对应要删除的索引加入到del_keys列表中
continue
if n == encrypt:
exist = True
for k in reversed(del_keys): # 将ENCRYPT_LIST列表中已到的秘钥删除
del ENCRYPT_LIST[k] if exist:
return False
ENCRYPT_LIST.append({'encrypt': encrypt, 'time': timestamp})
return True def api_auth(func):
def inner(request, *args, **kwargs):
if not api_auth_method(request): # 调用api_auth_method方法验证客户端秘钥是否有效
return JsonResponse({'code': 1001, 'message': 'API授权失败'}, json_dumps_params={'ensure_ascii': False})
return func(request, *args, **kwargs) return inner

Project/utils/auth.py 用于api认证的装饰器(插件代码)

from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^asset/', views.AssetView.as_view()),
]

urls.py

from django.shortcuts import HttpResponse
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt
import json from utils import auth class AssetView(View): @method_decorator(csrf_exempt) # 指定Home这个视图函数不使用csrf
def dispatch(self, request, *args, **kwargs):
result = super(AssetView,self).dispatch(request, *args, **kwargs)
return result @method_decorator(auth.api_auth)
def get(self,request):
return HttpResponse('api认证成功') @method_decorator(auth.api_auth)
def post(self,request):
print(request.POST)
print(request.body)
return HttpResponse(json.dumps({'status':'ok'}))

views.py使用插件进行API验证

import hashlib,time,requests,json
key = '299095cc-1330-11e5-b06a-a45e60bec08b' # 与服务器端加密字符串相同 # auth_key函数用来生成验证秘钥
def auth_key():
ha = hashlib.md5(key.encode('utf-8'))
time_span = time.time()
ha.update(bytes("%s|%f" % (key, time_span), encoding='utf-8'))
encryption = ha.hexdigest()
result = "%s|%f" % (encryption, time_span)
return {'auth-key': result} ####################### 1、发送get请求 ###########################
headers = {}
headers.update(auth_key())
response_get = requests.get( # 获取今天未采集资产的主机名列表
url='http://127.0.0.1:8000/asset/',
headers=headers,
data={'user': 'alex', 'pwd': ''}, # 通过请求体传递数据:post方式
) print('get:',response_get.text) ####################### 2、发送post请求 ###########################
headers = {}
headers.update(auth_key())
response_post = requests.post( # 获取今天未采集资产的主机名列表
url='http://127.0.0.1:8000/asset/',
headers=headers,
json={'user': 'tom', 'pwd': ''}, # 通过请求体传递数据:post方式
) print('post:',response_post.text)

在任意位置创建客户端test.py文件进行测试

   3、api认证精简版原理解析

from django.shortcuts import HttpResponse
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt
import json,time,hashlib APPID = "afafdsafdsfsdfdsa" visited = [] class AssetView(View): @method_decorator(csrf_exempt) # 指定Home这个视图函数不使用csrf
def dispatch(self, request, *args, **kwargs):
result = super(AssetView,self).dispatch(request, *args, **kwargs)
return result def get(self,request):
# req_appid = "d23672549e553b031756be33b1314573|1516174765.7812178"
req_appid = self.request.META.get('HTTP_APPID',None)
v, client_time = req_appid.split('|') current_time = time.time()
float_client_time = float(client_time) # 第一关:如果请求过来的时间距当前时间大于10秒,验证失败
if current_time - 10 > float_client_time:
return HttpResponse("验证失败") # 第二关:如果这个请求已经来过一次了,验证失败
if req_appid in visited:
return HttpResponse("验证失败") m = hashlib.md5()
m.update(bytes(APPID + client_time, encoding='utf-8'))
new_appid = m.hexdigest() # 第三关:判断v是否等于 APPID + client_time 的md5值
if new_appid == v:
visited.append(new_appid)
return HttpResponse('...')
else:
return HttpResponse('去你的吧') def post(self,request): return HttpResponse(json.dumps({'status':'ok'}))

服务器端:views.py

appid = "afafdsafdsfsdfdsa"

import requests,hashlib,time

current_time = str(time.time())

m = hashlib.md5()
m.update(bytes(appid + current_time,encoding='utf-8'))
new_appid = m.hexdigest() new_new_id = "%s|%s"%(new_appid,current_time) print(new_new_id) response = requests.get('http://127.0.0.1:8000/asset/',
# params={'appid':appid},
headers={'appid':new_new_id},
) response.encoding = 'utf-8' print('response',response.text) response2 = requests.post('http://127.0.0.1:8000/asset/',
# params={'appid':appid},
headers={'appid':new_new_id},
)
print(response2.text)

客户端test.py

05: api认证的更多相关文章

  1. [ Laravel 5.3 文档 ] 安全 ―― API认证(Passport)保障安全性。

    1.简介 Laravel通过传统的登录表单已经让用户认证变得很简单,但是API怎么办?API通常使用token进行认证并且在请求之间不维护session状态.Laravel使用LaravelPassp ...

  2. laravel Passport - 创建 REST API 用户认证以及Dingo/Api v2.0+Passport实现api认证

    第一部分: 安装passport 使⽤ Composer 依赖包管理器安装 Passport : composer require laravel/passport 接下来,将 Passport 的服 ...

  3. spring jwt springboot RESTful API认证方式

    RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authentication)和授权(Authorization)过程,保证API的安全性. Authenticatio ...

  4. Angularjs 通过asp.net web api认证登录

    Angularjs 通过asp.net web api认证登录 Angularjs利用asp.net mvc提供的asp.net identity,membership实现居于数据库的用户名/密码的认 ...

  5. Python开发【Django】:日志记录、API认证

    日志记录: 调用同一个对象,分别记录错误日志和运行日志 自定义日志类: class Logger(object): __instance = None def __init__(self): self ...

  6. Django REST framework 之 API认证

    RESTful API 认证 和 Web 应用不同,RESTful APIs 通常是无状态的, 也就意味着不应使用 sessions 或 cookies, 因此每个请求应附带某种授权凭证,因为用户授权 ...

  7. Laravel 的 API 认证系统 Passport 三部曲(二、passport的具体使用)

    GQ1994 关注 2018.04.20 09:31 字数 1152 阅读 1316评论 0喜欢 1 参考链接 Laravel 的 API 认证系统 Passport 三部曲(一.passport安装 ...

  8. Yii2.0 RESTful API 认证教程

    认证介绍 和Web应用不同,RESTful APIs 通常是无状态的, 也就意味着不应使用 sessions 或 cookies, 因此每个请求应附带某种授权凭证,因为用户授权状态可能没通过 sess ...

  9. laravel使用JWT做API认证

    最近项目做API认证,最终技术选型决定使用JWT,项目框架使用的是laravel,laravel使用JWT有比较方便使用的开源包:jwt-auth.php 后端实现JWT认证方法 使用composer ...

随机推荐

  1. git 出现 refusing to merge unrelated histories 解决

    如果出现refusing to merge unrelated histories,使用以下方法即可 git pull origin master --allow-unrelated-historie ...

  2. MongoDB的数据恢复

    当MongoDB正在插入或更新数据时,若突然出现断电或者不可逆转的摧毁性事件发生时,MongoDB没有像oracle或sql server这种关系型数据库提供事物机制,所以会产生垃圾数据.但Mongo ...

  3. centos7 卸载和安装最新版本docker-ce,配置阿里云加速

    一.yum卸载.安装 1.卸载老版本的 docker 及其相关依赖 sudo yum remove docker docker-common container-selinux docker-seli ...

  4. div+css网页标准布局实例教程(二)

    五.布局页面——头部和导航 有了上边的基础,下面的任务就是要利用html和css制作完成一个完整的网页了.先从头部开始,第三小节时我们已经把整体框架给搭建好了,就像盖房子一样,整体结构已经出来了,下面 ...

  5. 【Python接口测试】简单系统登录接口测试实例

    我们可以用Jmeter做接口测试,但是呢个人觉得那个有点局限性,用python就灵活很多, 可以按自己的思路来构建比较灵活,下面给大家介绍一个简单的接口测试实例. 一.我们的思路如下: 首先我们要弄清 ...

  6. python 基础3 函数

    函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,具体区别,我们后面会讲,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或 ...

  7. 时间序列深度学习:状态 LSTM 模型预測太阳黑子(一)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/kMD8d5R/article/details/82111558 作者:徐瑞龙,量化分析师,R语言中文 ...

  8. 解决PHPStorm经常卡顿现象 调整内存限制

    https://www.jisec.com/other/451.html 为什么调整内存? 最近发现PHPstorm在打开一些大点的js, html文件时,会非常的卡顿,这个主要的原因是因为设置的内存 ...

  9. [py]str list切片-去除字符串首尾空格-递归思想

    取出arr的前几项 #方法1 print([arr[0], arr[1]]) #方法2 arr2 = [] for i in range(2): arr2.append(arr[i]) print(a ...

  10. Andrew Ng-ML-第九&十章-神经网络

    1.神经网络模型1 图1 这是一个神经网络的模型,通常设置一个x0,作为偏执单元或者偏置(bias)神经元. 图2 这里最后一句话,说的是系数矩阵θ,神经网络模型中,如果当前在j层有s_j个单元,在j ...