zoukankan      html  css  js  c++  java
  • Django-api认证

    验证过程:每一个中控机有一个key,然后获取到当前时间戳。把key和当前时间戳这两个值进行一次加密,加密之后得到加密的戳,把加密的戳和当前获取的时间戳用管道符分割开生成一个大的字符串(加密戳|时间戳)后,发到服务器端。服务器端也有一个跟中控机一样的key,再把从客户端传过来的时间戳拿来跟key进行一次加密后做比较确定是否一样。但这种方式有漏洞,假如别人在中间获取了你的url之后就会永远向你发数据,所以在这个基础上加了一个超时时间和访问记录做限制。
    a. 时间超时
    b. 访问记录
    c. 加密后进行比较
    ~~
    (1)URL:django_apidjango_apiurls.py

    from django.conf.urls import url,include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^api/', include('api.urls')),  #以api开头转发到api项目里的url
    ]

    (2)URL:django_apiapiurls.py

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

    (3)视图函数:django_apiapiviews.py

    #验证了三层:1.时间,2在这个时间以内是否来过,3.反解进行验证
    from django.shortcuts import render,HttpResponse
    from django.views.decorators.csrf import csrf_exempt,csrf_protect   #关掉csrf
    import hashlib
    import time
    ck = "8kasoimnasodn8687asdfkmasdf"
    
    auth_list=[]                                                #定义空列表(要用缓存服务器做超时时间)
    
    @csrf_exempt                                                #不受csrf保护
    def asset(request):                                        #所有请求都封装在request对象里
        # print(request.method)                                 #打印接收什么方式提交
        # print(request.POST)
        # print(request.GET)
        # print(request.body)                                   #POST接收json序列化的数据后
        auth_key_time = request.META['HTTP_AUTHKEY']          #authkey_time是客户端发来的md5+key十六进制数据字符串值+客户端的时间戳的字符串
        auth_key_client,client_ctime = auth_key_time.split('|') #auth_key_client是客户端传md5+key,client_ctime客户端的时间戳的字符串+客户端传的时间戳
        server_current_time = time.time()                       #获取服务器当前时间戳字符串
        if server_current_time-5 > float(client_ctime):       #服务端当前时间戳往后推300秒还大于客户端发过来的时间戳
           return HttpResponse('时间太久远了')                #时间太久远了,直接忽略掉
        if auth_key_time in auth_list:                         #如果authkey_time在列表auth_list说明之前访问过了
           return HttpResponse('你来晚了')
        #如果上面验证成功了下面没成功说明用户自己写了一大堆key
        key_time = "%s|%s" %(ck,client_ctime,)                 #ck:本地的key,客户端传的时间戳
        m = hashlib.md5()
        m.update(bytes(key_time, encoding='utf-8'))            #把md5+key | 当前时间戳加进来
        authkey = m.hexdigest()                                 #生成一个md5+key+当前时间戳的字符串
    
        if authkey != auth_key_client:                          #如果本地的authkey跟客户端发来的auth_key_client不等于
            return HttpResponse('授权失败')
        auth_list.append(auth_key_time)                         #验证成功的加到访问过的列表auth_list里
        print(auth_list)
    
        if request.method == 'POST':                                    #如果接收的是POST方式
            import json
            host_info = json.loads(str(request.body,encoding='utf-8'))   #反序列化
            print(host_info)
        return HttpResponse('成功')

    启动api后等待客户端发数据:
    (1)客户端代码:

    import requests
    import hashlib                                         #md5
    import time
    current_time = time.time()                              #当前时间戳
    app_id = "8kasoimnasodn8687asdfkmasdf"             #key
    app_id_time = "%s|%s" %(app_id,current_time,)          #拼接成:key | 当前时间戳
    m = hashlib.md5()                                       #调用hashlib里的md5()生成一个md5的hash对象赋值m
    m.update(bytes(app_id_time,encoding='utf-8'))          #用update方法对字符串app_id_time进行md5加密的更新处理
    authkey = m.hexdigest()                                 #生成一个md5+key的十六进制数据字符串值
    
    authkey_time = "%s|%s" %(authkey,current_time,)        #authkey_time是md5+key十六进制数据字符串值 | 当前时间戳的字符串
    print(authkey_time)
    
    host_data = {                                           #取的主机信息
        'status': True,
        'data':{
            'hostname': 'c1.com',
            'disk': {'status':True,'data': 'xxx'},
            'mem': {'status':True,'data': 'xxx'},
        }
    }
    
    response = requests.post(                               #requests模块以post方式把host_data发http请求,response拿到发送后的返回值(http发送后返回的所有的值)
        url='http://127.0.0.1:8080/api/asset/',
        json=host_data,                                     #json把字典序列化成字符串后把host_data请求体POST形式传值到body
        headers={'authkey': authkey_time}                 #请求头headers放验证信息:authkeymd5+key+当前时间戳的字符串,authkey_time是md5+key+当前时间戳的字符串 | 当前时间戳的字符串
    )
    print(response.text)                                    #打印返回的值

    执行客户端后服务端接收数据:
    ['eb7259b288e686c0ad09e3ab8bdf049e|1554365241.2854595']
    {'status': True, 'data': {'hostname': 'c1.com', 'mem': {'status': True, 'data': 'xxx'}, 'disk': {'status': True, 'data': 'xxx'}}}
    客户端返回:
    eb7259b288e686c0ad09e3ab8bdf049e|1554365241.2854595
    成功

  • 相关阅读:
    系统维护相关问题
    Python环境维护
    哈希表解决字符串问题
    论文笔记二:《A Tutoral on Spectral Clustering》
    论文笔记之哈希学习比较--《Supervised Hashing with Kernels》《Towards Optimal Binary Code Learning via Ordinal Embedding》《Top Rank Supervised Binary Coding for Visual Search》
    Java中String、StringBuffer、StringBuilder的比较与源 代码分析
    浙大pat1040 Longest Symmetric String(25 分)
    浙大pat1039 Course List for Student(25 分)
    浙大pat---1036 Boys vs Girls (25)
    百炼oj-4151:电影节
  • 原文地址:https://www.cnblogs.com/xixi18/p/10655357.html
Copyright © 2011-2022 走看看