关键词:
Tronado的web应用安全(cookie和CSRF/XSRF)
安全cookies是web应用的安全防范之一,浏览器中的cookies存储了用户的个人信息,当然包括了某些重要的敏感的信息,如果一些恶意的脚本得到甚至修改了用户的cookies的信息,用户的信息就得不到安全的保障,所以应该对用户的cookies进行保护。Tornado的安全cookies可以对cookies签名进行安全加密,已检查cookies是否被修改过,因为恶意脚本不知道安全密钥,所以无法修改(但是恶意脚本仍然可以截获cookies来“冒充”用户,只是不能修改cookies而已,这也是另外一个安全隐患,本文并不讨论这点)。
Tornado的get_secure_cookie()和set_secure_cookie()可以安全的获取和发送浏览器的cookies,可以防止浏览器中的恶意修改,但是为了使用这个功能,必须在tornado.web.Application的settings中设置cookie_secret,其值为一个唯一的随机字符串(比如:base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes)可以产生一个唯一的随机字符串)。
CSRF或XSRF,即跨站请求伪造,是web应用都涉及到的一个安全漏洞,它利用了浏览器的一个安全漏洞:浏览器允许恶意攻击者在受害者网站注入脚本使未授权请求代表一个已登录用户。即别人可以“冒充”你做一些事情,而服务器也会认为这些操作是你做的。
为了防止XSRF攻击,应该注意:一是开发者考虑某些重要的请求时需要使用POST方法,二是Tornado的一个防范伪造POST的功能(这个功能是一种策略,tornado也实现了这种策略),就是在每个请求中包含一个参数值(隐藏的HTML表单元素值)和存储的cookie值,若两者(称之为令牌)匹配上了,则证明请求有效,当某个不可信的站点没有访问cookie数据的权限时,它就不能再请求中包含这个令牌cookie值,自然就无法发送有效的请求了。tornado中使用这个功能需要在tornado.web.Application的settings中设置xsrf_cookies,值为True,同时必须在HTML的表单中包含xsrf_form_html()函数,以此形成cookie令牌。
tornado的用户验证可以使用装饰器@tornado.web.authenticated,使用这个装饰器时需注意:①必须重写get_current_user()方法,这个返回的值将赋给self.current_user,②被装饰的方法被执行前会检查self.current_user的bool值是否为False(默认是None),若为False则会重定向到tornado.web.Application的settings中login_url指定的URL,③需要在tornado.web.Application的settings中login_url的URL,以便用户验证self.current_user之前可以重定向到这个URL。④当Tornado构建重定向URL时,它还会给查询字符串添加一个next参数,其值为重定向之前的URL,可以使用如self.redirect(self.get_argument(‘next‘, ‘/‘))这样的语句在用户验证成功后回到原来的页面。
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 import tornado.httpserver 4 import tornado.ioloop 5 import tornado.web 6 import tornado.options 7 import os.path 8 import base64 9 import uuid 10 11 from tornado.options import define, options 12 13 define(‘port‘, default=8000, help=‘run on the given port‘, type=int) 14 15 16 class BaseHandler(tornado.web.RequestHandler): 17 def get_current_user(self): 18 """重写此方法,返回的值将赋给self.current_user""" 19 return self.get_secure_cookie(‘username‘) # 获取cookies中username的值 20 21 22 class LoginHandler(BaseHandler): 23 def get(self): 24 self.render(‘login.html‘) 25 26 def post(self): 27 self.set_secure_cookie(‘username‘, self.get_argument(‘username‘)) # 将请求中的username值赋给cookie中的username 28 self.redirect(‘/‘) 29 30 31 class HomeHandler(BaseHandler): 32 @tornado.web.authenticated # 使用此装饰器必须重写方法get_current_user 33 def get(self): 34 """被@tornado.web.authenticated装饰的方法被执行前会检查self.current_user的bool值是否为False,不为False时才会执行此方法""" 35 self.render(‘index.html‘, user=self.current_user) 36 37 38 class LogoutHandler(BaseHandler): 39 def get(self): 40 if self.get_argument(‘logout‘, None): 41 self.clear_cookie(‘username‘) # 清楚cookies中名为username的cookie 42 self.redirect(‘/‘) 43 44 45 if __name__ == ‘__main__‘: 46 tornado.options.parse_command_line() 47 48 settings = 49 ‘template_path‘: os.path.join(os.path.dirname(__file__), ‘templates‘), 50 ‘cookie_secret‘: base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes), # 设置cookies安全,值为一个唯一的随机字符串 51 ‘xsrf_cookies‘: True, # 设置xsrf安全,设置了此项后必须在HTML表单中包含xsrf_form_html() 52 ‘login_url‘: ‘/login‘ # 当被@tornado.web.authenticated装饰器包装的方法检查到self.current_user的bool值为False时,会重定向到这个URL 53 54 55 application = tornado.web.Application([ 56 (r‘/‘, HomeHandler), 57 (r‘/login‘, LoginHandler), 58 (r‘/logout‘, LogoutHandler) 59 ], **settings) 60 61 http_server = tornado.httpserver.HTTPServer(application) 62 http_server.listen(options.port) 63 tornado.ioloop.IOLoop.instance().start()
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Welcom Back!</title> 6 </head> 7 <body> 8 <h1>Welcom back, user </h1> 9 </body> 10 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Please Log In</title> 6 </head> 7 <body> 8 <form action="/login" method="POST"> 9 % raw xsrf_form_html() %<!-- 这其实是一个隐藏的<input>元素,定义了“_xsrf”的值,会检查POST请求以防止跨站点请求伪造 --> 10 Username: <input type="text" name="username" /> 11 <input type="submit" value="Log In" /> 12 </form> 13 </body> 14 </html>
tornado之初学者
Tornado特点一句话简介:Tornado是非阻塞式的Web服务器,速度非常快,每秒可以处理数以千计的链接,因此Tornado是实时Web服务的一个理想框架。一、安装Tornado使用pip安装即可:pipinstalltornado二、运行Tornado的helloworld所需的基本组成#... 查看详情
pythontornado初学笔记之表单与模板
Tornado中的表单和HTML5中的表单具有相同的用途,同样是用于内容的填写。只是不同的是Tornado中的表单需要传入到后台,然后通过后台进行对模板填充。 模板:是一个允许嵌入Python代码片段的HT... 查看详情
tornado之异步非阻塞(代码片段)
同步模式:同步模式下,只有处理完前一个任务下一个才会执行classMainHandler(tornado.web.RequestHandler):defget(self):time.sleep(10)self.write("Hello,world")application=tornado.web.Application([(r"/index",MainHandler),])if__na 查看详情
tornado之模板(代码片段)
...静态页面文件(下载静态文件资源),我们来看下如何用tornado提供静态文件。static_path我们可以通过向web.Application类的构造函数传递一个名为static_path的参数来告诉Tornado从文件系统的一个特定位置提供静态文件,如: 查看详情
抽屉之tornado实战--form表单验证(代码片段)
在这里,我们把form表单验证的代码进行工具化了,以后稍微修改一下参数就可以拿来用了 先贴上代码forms.pyfrombackend.formimportfieldsclassBaseForm:def__init__(self):self._value_dict=self._error_dict=self._valid_status=Truedefvalid(self,handler) 查看详情
框架之tornado(简单介绍)(代码片段)
引言回想Django的部署方式以Django为代表的pythonweb应用部署时采用wsgi协议与服务器对接(被服务器托管),而这类服务器通常都是基于多线程的,也就是说每一个网络请求服务器都会有一个对应的线程来用web应用(如Django)进行... 查看详情
抽屉之tornado实战--session工厂(工厂方法模式)(代码片段)
我之前写的session一般保存在服务器的内存里,那可以保存在缓存,或是数据库,那问题来了,不同地方,保存方式是不同的,所以需要定义不同的类,cache/redis/memcached类session.pyimportconfigfromhashlibimportsha1importosimporttimecreate_session_i... 查看详情
抽屉之tornado实战--数据库表设计(代码片段)
经过我们上次分析,数据库要有最基本的四张表,用户表,消息表,类型表,点赞表,评论表,接下来我们看着怎么设计吧 首先我们要清楚,表设计的代码是写在models下的用户表#一张表对应一个类classUserInfo(Base):#把表名赋... 查看详情
抽屉之tornado实战--装饰器实现用户登录状态验证(代码片段)
当然今天讲的验证,不只Tornado会用,以后用到web框架都会用到,最常见的场景就是只有用户登陆了才能执行某些操作,所以在执行这些操作前要先做登陆状态的验证。 比如:点赞,发布,评论等需要验证,都需要用到ifself.s... 查看详情
tornado之session实现(代码片段)
Tornado框架中,默认执行Handler的get/post等方法之前默认会执行initialize方法,所以可以通过自定义的方式使得所有请求在处理前执行操作importtornado.ioloopimporttornado.webimporttimeimporthashlib#将session_id保存在内存中classCache(object):def__init__(s... 查看详情
tornado系列项目之基于领域驱动模型架构设计的京东用户管理后台(代码片段)
本博文将一步步揭秘京东等大型网站的领域驱动模型,致力于让读者完全掌握这种网络架构中的“高富帅”。一、预备知识:1.接口:python中并没有类似java等其它语言中的接口类型,但是python中有抽象类和抽象方法。如... 查看详情
1.pythonweb框架tornado之web框架简单介绍模板语言介绍(代码片段)
...个tronado框架web项目介绍 a.首先创建一个demo文件importtornado.webimporttornado.ioloopclassMainHandler(tornado.web.RequestHandler):defget(self):#返回的是一个字符串self.write("Hello,world")#路由映射,路由系统application=tornado.web.Application([(r"/index",MainHandl... 查看详情
tornado异步之-协程与回调(代码片段)
...求回调 callback 处理异步官方例子#导入所需库fromtornado.httpclientimportAsyncHTTPClientdefasynchronous_fetch(url,callback):http_client=AsyncHTTPClient()defhandle_response(response):callback(response.body)http_client.fetch(url,callback=handle_response)当http_client处理请... 查看详情
python3之初学者常犯的5个错误(代码片段)
1.Creating acopyofdictionaryorlists.Wheneveryouneedtomakeacopyofadictionaryorlist,donotsimplyusetheassignmentoperator.Rightway:Usethecopy() ordeepcopy() method. 2.Dictionarykeys.Re 查看详情
c语言初学者之初识代码专项练习(代码片段)
🍊前言:自我介绍:Super大雄 🐻🐻🐻(萌新博主一枚)C语言专栏:0基础学C语言专栏LeetCode专栏:LeetCode专栏小伙伴们大家好,如果你是C语言初学者啊👨💻👨 查看详情
python之初学爬虫(代码片段)
一、开发工具:运行环境:python3.7 win10python第三方库:requests(自行安装) >>>cmd--->pipinstallrequests,具体不做介绍)二、检测是否安装成功 在命令行中输入python,敲击回车,进入python环境。 &... 查看详情
tornado框架初探(代码片段)
1、tornado概述Tornado就是我们在FriendFeed的Web服务器及其常用工具的开源版本。Tornado和现在的主流Web服务器框架(包括大多数Python的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其非阻塞的方式和对epoll... 查看详情
java虚拟机|jvm适合初学者入门(代码片段)
Java虚拟机|JVM【适合初学者入门】0.前言1.学习JVM的目的2.主要的虚拟机3.什么是虚拟机4.源代码到机器码的过程5.字节码文件的结构6.Java虚拟机内存结构7.JVM类的加载机制8.JVM垃圾回收机制9.JVM垃圾回收期10.垃圾回收的几种类型11.JVM... 查看详情