zoukankan      html  css  js  c++  java
  • Python api认证

    本节内容:

    • 基本的api
    • 升级的api
    • 终极版api

    环境:Djanao,

    项目名:api_auto,

    app:api

    角色:api端,客户端,黑客端

    1.基本的api

    【api端】

    #api_auto/urls.py
    from django.conf.urls import url,include
    from django.contrib import admin
    from api import urls
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^api/', include('api.urls')),
    ]
    #api/urls.py
    from django.conf.urls import url
    from . import views
    
    import include
    urlpatterns = [
        url(r'^asset.html', views.asset),
    ]
    #api/views.py
    from django.shortcuts import render,HttpResponse
    # Create your views here.
    
    def asset(request):
        print(request.POST)
        return  HttpResponse('api访问成功')

    #输出,这样api端就可以拿到客户端的数据
    <QueryDict: {'k2': ['sssss'], 'k1': ['v1sss']}

    【客户端】

    # -*- coding: UTF-8 -*-
    #blog:http://www.cnblogs.com/linux-chenyang/
    
    import  requests
    
    data_dict = {
        'k1':'v1sss',
        'k2':'sssss',
    }
    
    ret = requests.post(
        url='http://127.0.0.1:8000/api/asset.html',
        data=data_dict,
    )
    
    print(ret.text)

    #输出,api段会返回给客户端一个结果
    api访问成功

    2.升级的api

    由于上面这种方法没有认证,假如任何人都可以发post请求,很不安全,引出下面这种方法,让客户端带个key过来,api端先检查在不在我的列表里,不在的话就不允许访问。

    【api端】

    #api/views.py
    
    def asset(request):
        app_key_dict = {
            'de3908e1-31c3-4de8-a535-7830cca5a427':{'name':'中共中央国务院','level':10},
            'd7b64313-9e62-4441-9f10-b21288a1431a':{'name':'老男孩教育','level':1},
        }
        agent_app_key= request.GET.get('app_key')
        if agent_app_key in app_key_dict:
            name = app_key_dict[agent_app_key]['name']
            print(name)
            return HttpResponse('api访问成功!')
        else:
            return  HttpResponse('认证失败,不能访问api')
    #输出
    [08/Aug/2017 15:48:27] "POST /api/asset.html?app_key=de3908e1-31c3-4de8-a535-7830cca5a427 HTTP/1.1" 200 3
    中共中央国务院

    【客户端】

    import  requests
    
    app_key = 'de3908e1-31c3-4de8-a535-7830cca5a427'
    data_dict = {
        'k1':'v1',
        'k2':'v2',
    }
    
    ret = requests.post(
        url='http://127.0.0.1:8000/api/asset.html',
        params={'app_key':app_key},
        data=data_dict,
    )
    
    print(ret.text)

    这种方法有个弊端,假如黑客通过抓包或者其他方法获取到服务器的url,那么客户端依然可以访问。

    【黑客端】

    import  requests
    
    data_dict = {
        'k1':'v1sss',
        'k2':'sssss',
    }
    
    ret = requests.post(
        url='http://127.0.0.1:8000/api/asset.html?app_key=de3908e1-31c3-4de8-a535-7830cca5a427',
        data=data_dict,
    )
    
    print(ret.text)

    3.终极版api

    【api端】

    #api/views.py
    
    def asset2(request):
        '''
        用于验证3的加密匹配
        :param request:
        :return:
        '''
        def create_md5(app_key,app_secret,timestamp):
            import hashlib
            m = hashlib.md5(bytes(app_secret,encoding='utf-8'))
            temp = "%s|%s" %(app_key,timestamp,)
            m.update(bytes(temp,encoding='utf-8'))
            return m.hexdigest()
    
        '''
        api端存放的客户段的key
        '''
        app_key_dict = {
            '66244932-3a61-48c5-b847-9a750ba6567e':
                {
                    'name':'中共中央国务院',
                    'level': 10,
                    'secret': 'asd=asdfkdf',
                    'record': [
                        {'sign': '3a8530132a55512c9937c60df63ba868','timestamp': 1494042557.7139883}
                    ]
                },
            '49684626-71fc-450a-b2bb-dfde77d2cbd3': {'name':'老男孩教育','level': 1,'secret': 'as2dasdf=asdf','record': []},
        }
    
        """
        从客户发来的url后拿到所需要的数据,key
        """
        agent_app_key = request.GET.get('app_key')
        agent_app_sign = request.GET.get('app_sign')
        agent_app_timestamp = float(request.GET.get('app_timestamp'))
    
        """
        验证1.判断秘钥app_key正不正确
        """
        if agent_app_key not in app_key_dict:
            return HttpResponse('二货,一垒都上不了...')
    
        """
        验证2.客户端过来的key和服务器端之间时间不超过5秒
        """
        server_timestamp = time.time()
        if (server_timestamp - 5) > agent_app_timestamp:
            return HttpResponse('滚,时间怎么这么长...')
    
        """
        验证3.反解密,匹配加密的key是否正确,secret从api端拿
        """
        server_sign = create_md5(agent_app_key,app_key_dict[agent_app_key]['secret'],agent_app_timestamp)
        if agent_app_sign != server_sign:
            return HttpResponse('小样,你还给我修改url,太嫩了...')
    
        """
        验证4.有了一个访问的客户端,同样的key在不能访问
        """
        record_list = app_key_dict[agent_app_key]['record']
        for item in record_list:
            if agent_app_sign == item['sign']:
                return HttpResponse('煞笔,来晚了...')
    
        app_key_dict[agent_app_key]['record'].append({'sign': agent_app_sign,'timestamp': agent_app_timestamp})
    
        # 数据加密 rsa
        # http://www.cnblogs.com/wupeiqi/articles/6746744.html
    
        name = app_key_dict[agent_app_key]['name']
        return HttpResponse(name)
    api端
    import  requests,time
    def god2():
        """
        app_sign:这样就根据app_key+app_secret+timestamp生成动态的字符串
        :return:
        """
        def create_md5(app_key,app_secret,timestamp):
            import hashlib
            m = hashlib.md5(bytes(app_secret,encoding='utf-8'))
            temp = "%s|%s" %(app_key,timestamp,)
            m.update(bytes(temp,encoding='utf-8'))
            return m.hexdigest()
    
        app_key = '66244932-3a61-48c5-b847-9a750ba6567e'
        app_secret = "asd=asdfkdf"
        app_timestamp = time.time()
        app_sign = create_md5(app_key,app_secret,app_timestamp)
    
        """
        api请求:
        加密的app_sign和 app_key还有时间app_timestamp传到API
        但是app_secret不能传过去
        params:数据会存在url后面?app_sign=****&app_key=***
    
        """
        data_dict = {
            'k1':'v1',
            'v2':'v2'
        }
        ret = requests.post(
            url='http://127.0.0.1:8000/api/asset2.html',
            params={'app_sign': app_sign,"app_key": app_key, 'app_timestamp': app_timestamp},
            data=data_dict
        )
        print(ret.text)
    
    
    def god1():
        app_key = 'de3908e1-31c3-4de8-a535-7830cca5a427'
        data_dict = {
            'k1': 'v1',
            'k2': 'v2',
        }
    
        ret = requests.post(
            url='http://127.0.0.1:8000/api/asset.html',
            params={'app_key': app_key},
            data=data_dict,
        )
    
        print(ret.text)
    
    if __name__ == '__main__':
        #god1()
        god2()
    客户端
  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/linux-chenyang/p/7325903.html
Copyright © 2011-2022 走看看