python_way ,day23

1、api认证  、api加密动态请求

2、自定义session


一、api认证

首先提供api的公司,如支付宝,微信,都会给你一个用户id,然后还会让你下一个SDK,你使用SDK加上id做加密,访问商提供的域名进行验证

SDK,一个商户的加密程序。

二、动态地址认证:

为了避免黑客拦截你提交的请求,然后使用你提交的请求非法获取利益,所以我们就需要每次提交都需要改变一下url,这下你使用过的url就失去了作用。

(但是前提是你必须在他之前访问,如果比他访问的慢那就没有办法了)

所以我们就是制作一个动态的url给服务器

比如说md5与时间拼接后的字符串进行加密,就是服务器商提供的SDK我们使用它对服务器给我们提供的id进行加密

1.NB的加密算法:

  1. #!/usr/bin/env python3
  2. # Created by han on 2016/10/28
  3. import hashlib
  4. import time
  5.  
  6. #客户端的操作没客户端获取了服务器事先给的asdfasdf,这个值,然后使用官方规定的加密方法,这里就是用的md5做加密,然后把加密后的数值传给服务器,服务器用相同的方法解密
  7. def md5(arg):
  8. m = hashlib.md5()
  9. m.update(bytes(arg,encoding="utf8"))
  10. return m.hexdigest()
  11.  
  12. def new_str(arg):
  13. current_time = time.time()
  14. rer_str = "%s|%s" % (arg,current_time)
  15. md5_str = md5(rer_str)
  16. return md5_str,current_time #还需要把时间给服务器返回,好让他使用这个动态的字符串解密

2、向服务商提请求

  1. #!/usr/bin/env python3
  2. # Created by han on 2016/10/28
  3. import os,sys
  4. sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  5. import requests
  6. from module import client_publish
  7. # key = "asdaf" #因为静态的api会让黑客截取
  8. row_key = client_publish.new_str("asdfasdf") #row_key 是一个元组,上面返回的包括(加密串与当前时间)
  9. key="%s|%s" % row_key
  10. ret = requests.get("http://www.old.com:8888/main?app_id=%s"%key) #使用get方式请求服务器
  11. print(ret.text)

3、服务商接收请求,并且获取到动态的url,进行加密校验

  1. import os,sys, time
  2. sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  3. import tornado.web
  4. from module import client_publish
  5. APP_ID_LIST = [
  6. 'asdf',
  7. '',
  8. 'asdfasdf',
  9. ]
  10.  
  11. class MainHadler(tornado.web.RequestHandler):
  12. def get(self):
  13. md5_app_id = self.get_argument("app_id", None) #获取get的携带的请求
  14.      #先分割,获取时间与客户端的加密字符串
  15. time = md5_app_id.split("|")[1]
  16. client_md5 = md5_app_id.split("|")[0]
  17. #设置一个标志
  18. flag = False
  19. for i in APP_ID_LIST:
  20. server_str = "%s|%s" % (i, time)
  21. server_md5 = client_publish.md5(server_str)
  22. #这里也做md5加密,如果值和客户端传过来的值相等,那么就可以证明验证通过
  23.        if server_md5 == client_md5:
  24. flag = True
              break #认证成功后跳出  
  25. if flag:
  26. self.write("APP_ID") #相当于django的HTTPResponse
  27. else:
  28. self.write("滚")

但是这样貌似加密了,劫持后所有动态的url都可以使用!

所以我们就要规定一个有效时间,这个有效时间内他同一个客户端传来的url只能访问一次

然后把这些已经访问过得url存到redis,redis,指定这个redis中定期的数据清除。

  1. #!/usr/bin/env python3
  2. # Created by han on 2016/10/26
  3. import os, sys, time
  4. sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  5. import tornado.web
  6. from module import client_publish
  7. APP_ID_LIST = [
  8. 'asdf',
  9. '',
  10. 'asdfasdf',
  11. ]
  12.  
  13. valide_url = [] #这个列表就是维护一个已经验证通过,并且使用过的url,我们可以把这个列表放到redis中,每大于10秒清空它
  14.  
  15. class MainHadler(tornado.web.RequestHandler):
  16. def get(self):
  17.   st = time.time() #先生成本地时间
  18.   md5_app_id = self.get_argument("app_id", None) #获取get的携带的请求
  19.   client_md5, client_time = md5_app_id.split("|")
  20.   if float(client_time) < st - 10: #判断一,假如在10s内再次访问。不通过
  21.     self.write("滚1")
  22.     return
  23. if md5_app_id in valide_url: #如果md5在valid_url中,证明已经验证过了,不通过
  24.     self.write("滚2")
  25.     return
  26.   flag = False
  27. for i in APP_ID_LIST:
  28.     server_str = "%s|%s" % (i, client_time) , #如果黑客修改了时间,到这里利用时间做md5值加密的时候就和用户发来的不一样了!所有就能规避到用户发来的修改时间后的rul了
  29.     server_md5 = client_publish.md5(server_str)
  30.   if server_md5 == client_md5: #到这里就应该是第一次访问,并且通过了正确性验证
  31.     flag = True
  32.     valide_url.append(md5_app_id)    #因为是第一次访问,所以把刚刚验证的url添加到列表中
  33.     break #认证成功后跳出
  34.   if flag:
  35.     self.write("APP_ID") #相当于django的HTTPResponse
  36.   else:
  37.     self.write("滚3")
  38.  
  39. class CmdbHander(tornado.web.RequestHandler): #tornado内部使用反射来找到类中对应的方法
  40. #resutful变向资源编程,一个url通过不同的请求分配到不同的方法
  41. def get(self):
  42. # self.write("cmdb")
  43. a = [11, 22, 33, 44]
  44. self.render("index.html", li = a)
  45.  
  46. def post(self): #以post方式请求,
  47. user_info = []
  48. user = self.get_argument("user") #获取post请求的信息
  49. pwd = self.get_argument("password")
  50. user_info.append({"u": user, "p": pwd})
  51. self.redirect('/home') #跳转
  52.  
  53. class HomeHadler(tornado.web.RequestHandler):
  54. def get(self):
  55. self.render("home.html", user_info_list = USER_INFO) #模板渲染
  1. #!/usr/bin/env python3
  2. # Created by han on 2016/10/28
  3. import os,sys
  4. sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  5. import requests
  6. from module import client_publish
  7. # key = "asdaf" #因为静态的api会让黑客截取
  8. row_key = client_publish.new_str("asdfasdf")
  9. key="%s|%s" % row_key
  10. ret = requests.get("http://www.old.com:8888/main?app_id=%s"%key) #使用get方式请求服务器
  11. print(ret.text)

二、自定义session

cookie:写在浏览器上的一个键值对

session:写在服务器上的,key就是cookie的value,value里是对应的一些值

Django,session使用时用到了类中的一个方法。

session的预备知识:

1、定义字典样式

2、反射

  1. class Text:
  2. def get(self):
  3. print("get")
  4. def set(self):
  5. print("set")
  6.  
  7. obj = Text()
  8. func = getattr(obj,'get')
  9. func()

反射

3、tornado执行类方法的钩子:

  1. #我们在请求cmdb.old.com/home的时候直接执行了 HomeeHadler中的get方法
  2. #是应为Tonardo内部肯定将 HomeHadler实例化了
  3. # obj = HomeHadler()
  4. # obj.get()
  5. #如果我们想在执行get方法前添加一个方法,哪我们就要讲HomeHadler的构造方法中添加一个功能,就可以了
  6. #HomeHadler我们没有写构造方法,哪我们就去找他的父类的构造方法
  7. #在tornado.web.RequestHandler内部我们看到了这个钩子,是预留好的,自己可以自定义的
  8. # def initialize(self):
  9. # pass
  10. #我们就可以修改源码了,但是如果修改了源码,哪我们在线上线下布置的环境中就都需要修改这个源码,
  11. #所以我们就使用继承的方式,将这个initialize使用上
  1. class HomeHadler(tornado.web.RequestHandler):
  2. def initialize(self):
  3. print("123123") #此时就会先执行initialize
  4.  
  5. def get(self):
  6. self.write("OK")

如果一个类使用上面的解决方式就可以实现了。但是如果要是很多类都需要使用initialize方法,并且还需要修改,上面的方法就有些蠢了

那么我们就可以使用一个继承来解决这个问题了。

  1. class MyRequestHandler(tornado.web.RequestHandler):
  2. def initialize(self):
  3. print("")
  4.  
  5. class HomeHadler(MyRequestHandler):
  6.  
  7. def get(self):
  8. self.write("OK")
  9.  
  10. class HostHadler2(MyRequestHandler): #这种方式的话就可以方便统一使用,统一修改了
  11. def get(self):
  12. self.write("OK")

思考:

  1. HomeHadler 或者 HostHadler2中的self MyRequestHandler中的self是否一样
  1. 是一样的
  2. 因为在我们创建对象的时候
  3. obj = HostHadler()
  4. obj.initialize() 如果在HomeHadler中没有,就回去他的父类MyRequestHandler中寻找,所以他们两个obj对象是一个,这样就可以判断出self是一个了

答案

所以我们就可以把代码改动一下做个试验

  1. lass MyRequestHandler(tornado.web.RequestHandler):
  2. def initialize(self):
  3. self.sss = {"k",123}
  4.  
  5. class HomeHadler(MyRequestHandler):
  6.  
  7. def get(self):
  8. print(self.sss)
  9. self.write("OK")
  10.  
  11. 这会执行结果就是
  1. "k",123

言归正传:给浏览器的cookie设置session

  1. application = tornado.web.Application([
    (r"/main", home.MainHadler),
    ], **settings) #只需要在application这里增加setttings这个配置
  2.  
  3. application.add_handlers("cmdb.old.com",[
    (r"/home", home.HomeHadler),
    ])
  1. container = {}
  2.  
  3. class Session:
  4. def __init__(self, handler): #3、handler就是之前传递过来的handler方法,所以它也会有setcookie方法。
  5. self.cookie = client_publish.md5_str() #先生成一个变化的cookie
  6. client_cookie = handler.get_cookie("__session_id__") #获取客户端的cookie
  7. if client_cookie: #如果获取到cookie
  8. if client_cookie in container: #检查这个cookie是否存在在container中
  9. #如果客户端访问的md5在我的列表中证明是真的
  10. print("有cookie")
  11. self.r_str = client_cookie #设置一个字段,以备以后调用
  12. else:#否则就是假的
  13. handler.set_cookie("__session_id__",self.cookie) #设置一个新的cookie
  14. print("假的cookie")
  15. container[self.cookie] = {} #把这个cookie放在字典中
  16. self.r_str = self.cookie #同样因为是新生成的cookie,还是设置一个字段,以备后患
  17. else:
  18. container[self.cookie] = {} #如果没有设置cookie,第一次访问
  19. print("没有cookie")
  20. handler.set_cookie("__session_id__", self.cookie) #设置cookie
  21. self.r_str = self.cookie
  22.  
  23. class MyRequestHandler(tornado.web.RequestHandler):
  24. def initialize(self):                  ##2、执行这个initalize函数
  25. #在RequestHandler中有set_cookie方法
  26. self.key = Session(self) #我们把self传递给Session 自定义的这个类中
  27.  
  28. class HomeHadler(MyRequestHandler): ## 1、第一部会先执行这个函数并向客户端浏览器会写 set cookie,但在回写之前,执行了父类中的构造函数
  29. def get(self):
  30. #self.set_cookie() 因为这里继承了MyRequestHandler,所以在这里也有set cookie方法
  31. self.write("set cookie")
  1.  

python_way ,day23 API的更多相关文章

  1. python_way ,day22 tonardo

    python_way day22 1.tonardo 2.cookie 3.api认证 一.tonardo: a.tonardo 初识 #!/usr/bin/env python3# Created ...

  2. python_way day12 sqlalchemy,原生mysql命令

    python_way day12  sqlalchemy,mysql原生命令 1.sqlalchemy 2.mysql 原生命令 一,sqlalchemy SQLAlchemy本身无法操作数据库,其必 ...

  3. day23 框架之基础加强

    day23 框架之基础加强 今日任务 aptana(javascript的eclipse插件):http://www.cnblogs.com/terrylin/archive/2012/06/20/2 ...

  4. python_way ,day22 tonardo,jsonp

    python_way day22 1.tonardo 2.cookie 3.api认证 一.tonardo: a.tonardo 初识 #!/usr/bin/env python3# Created ...

  5. 干货来袭-整套完整安全的API接口解决方案

    在各种手机APP泛滥的现在,背后都有同样泛滥的API接口在支撑,其中鱼龙混杂,直接裸奔的WEB API大量存在,安全性令人堪优 在以前WEB API概念没有很普及的时候,都采用自已定义的接口和结构,对 ...

  6. 12306官方火车票Api接口

    2017,现在已进入春运期间,真的是一票难求,深有体会.各种购票抢票软件应运而生,也有购买加速包提高抢票几率,可以理解为变相的黄牛.对于技术人员,虽然写一个抢票软件还是比较难的,但是还是简单看看123 ...

  7. 几个有趣的WEB设备API(二)

    浏览器和设备之间还有很多有趣的接口, 1.屏幕朝向接口 浏览器有两种方法来监听屏幕朝向,看是横屏还是竖屏. (1)使用css媒体查询的方法 /* 竖屏 */ @media screen and (or ...

  8. html5 canvas常用api总结(三)--图像变换API

    canvas的图像变换api,可以帮助我们更加方便的绘画出一些酷炫的效果,也可以用来制作动画.接下来将总结一下canvas的变换方法,文末有一个例子来更加深刻的了解和利用这几个api. 1.画布旋转a ...

  9. JavaScript 对数据处理的5个API

    JavaScript对数据处理包括向上取整.向下取整.四舍五入.固定精度和固定长度5种方式,分别对应ceil,floor,round,toFixed,toPrecision等5个API,本文将对这5个 ...

随机推荐

  1. sql多表查询(out join,inner join, left join, right join)

    left join以左表为基准显示所有左表的信息,在on中有符合条件的其他表也显示出来 right join则相反 inner join的只显示on中符合条件的 1 使用多个表格 在「world」资料 ...

  2. 表数据文件DBF的读取和写入操作

    import sys import csv import struct import datetime import decimal import itertools from cStringIO i ...

  3. Json常见问题

    1.创建包含 JSON 语法的 JavaScript 字符串: var txt = '{ "employees" : [' + '{ "firstName":& ...

  4. easyui-tabs图标(获取焦点时显示图标,失去焦点时隐藏图标)

    获取焦点时显示图标,失去焦点时隐藏图标 <script type="text/javascript"> $('#_progress').tabs({ onSelect: ...

  5. codeigniter db操作方法

    链接数据库 ——- $this->load->database();//手动连接数据库 //连接多数据库 $DB1 = $this->load->database(‘group ...

  6. [C++][代码库]Vector3空间向量类

    本文用C++实现一个简单的Vector3类的功能,暂时有的功能是: 1 + - * /算术运算 2 向量的数量积,又叫:点乘 3 向量的向量积,又叫:叉乘 4 向量单位化(normalization) ...

  7. ACM题目————Equations

    Description Consider equations having the following form: a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 a, b, c, d a ...

  8. SlickGrid example 2: 按想要的风格展示列

    先上效果图. 代码: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http:// ...

  9. JQuery-遮罩层

    HTML <html> <head> <link href="StyleSheet.css" rel="stylesheet" t ...

  10. selenium帮助手册以及 webdriver的各种driver

    帮助手册 http://selenium-python.readthedocs.io/locating-elements.html 转载于:http://blog.csdn.net/five3/art ...