forked from qiwsir/StarterLearningPython
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
254 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
>我亲爱的弟兄们,这是你们所知道的。但你们个人要快快地听,慢慢地说,慢慢地动怒,因为人的怒气并不成就神的义。所以,你们要脱去一切的污秽和盈余的邪恶,存温柔的心领受那所栽种的道,就是能救你们灵魂的道。(JAMES 1:19-21) | ||
#用tornado做网站(6) | ||
|
||
在[上一节](./307.md)中已经对安全问题进行了描述,另外一个内容是不能忽略的,那就是用户登录之后,对当前用户状态(用户是否登录)进行判断。 | ||
|
||
##用户验证 | ||
|
||
用户登录之后,当翻到别的目录中时,往往需要验证用户是否处于登录状态。当然,一种比较直接的方法,就是在转到每个目录时,都从cookie中把用户信息,然后传到后端,跟数据库验证。这不仅是直接的,也是基本的流程。但是,这个过程如果总让用户自己来做,框架的作用就显不出来了。tornado就提供了一种用户验证方法。 | ||
|
||
为了后面更工程化地使用tornado编程。需要将前面的已经有的代码进行重新梳理。我只是将有修改的文件代码写出来,不做过多解释,必要的有注释,相信读者在前述学习基础上,能够理解。 | ||
|
||
在handler目录中增加一个文件,名称是base.py,代码如下: | ||
|
||
#! /usr/bin/env python | ||
# coding=utf-8 | ||
|
||
import tornado.web | ||
|
||
class BaseHandler(tornado.web.RequestHandler): | ||
def get_current_user(self): | ||
return self.get_secure_cookie("user") | ||
|
||
在这个文件中,目前只做一个事情,就是建立一个名为BaseHandler的类,然后在里面放置一个方法,就是得到当前的cookie。在这里特别要向读者说明,在这个类中,其实还可以写不少别的东西,比如你就可以将数据库连接写到这个类的初始化`__init__()`方法中。因为在其它的类中,我们要继承这个类。所以,这样一个架势,就为读者以后的扩展增加了冗余空间。 | ||
|
||
然后把index.py文件改写为: | ||
|
||
#!/usr/bin/env python | ||
# coding=utf-8 | ||
|
||
import tornado.escape | ||
import methods.readdb as mrd | ||
from base import BaseHandler | ||
|
||
class IndexHandler(BaseHandler): #继承base.py中的类BaseHandler | ||
def get(self): | ||
usernames = mrd.select_columns(table="users",column="username") | ||
one_user = usernames[0][0] | ||
self.render("index.html", user=one_user) | ||
|
||
def post(self): | ||
username = self.get_argument("username") | ||
password = self.get_argument("password") | ||
user_infos = mrd.select_table(table="users",column="*",condition="username",value=username) | ||
if user_infos: | ||
db_pwd = user_infos[0][2] | ||
if db_pwd == password: | ||
self.set_current_user(username) #将当前用户名写入cookie,方法见下面 | ||
self.write(username) | ||
else: | ||
self.write("-1") | ||
else: | ||
self.write("-1") | ||
|
||
def set_current_user(self, user): | ||
if user: | ||
self.set_secure_cookie('user', tornado.escape.json_encode(user)) #注意这里使用了tornado.escape.json_encode()方法 | ||
else: | ||
self.clear_cookie("user") | ||
|
||
class ErrorHandler(BaseHandler): #增加了一个专门用来显示错误的页面 | ||
def get(self): #但是后面不单独讲述,读者可以从源码中理解 | ||
self.render("error.html") | ||
|
||
在index.py的类IndexHandler中,继承了BaseHandler类,并且增加了一个方法set_current_user()用于将用户名写入cookie。请读者特别注意那个tornado.escape.json_encode()方法,其功能是: | ||
|
||
>tornado.escape.json_encode(value) | ||
> JSON-encodes the given Python object. | ||
如果要查看源码,可以阅读:[http://www.tornadoweb.org/en/branch2.3/escape.html](http://www.tornadoweb.org/en/branch2.3/escape.html) | ||
|
||
这样做的本质是把user转化为json,写入到了cookie中。如果从cookie中把它读出来,使用user的值时,还会用到: | ||
|
||
>tornado.escape.json_decode(value) | ||
> Returns Python objects for the given JSON string | ||
它们与[json模块中的dump()、load()](./227.md)功能相仿。 | ||
|
||
接下来要对user.py文件也进行重写: | ||
|
||
#!/usr/bin/env python | ||
# coding=utf-8 | ||
|
||
import tornado.web | ||
import tornado.escape | ||
import methods.readdb as mrd | ||
from base import BaseHandler | ||
|
||
class UserHandler(BaseHandler): | ||
@tornado.web.authenticated | ||
def get(self): | ||
#username = self.get_argument("user") | ||
username = tornado.escape.json_decode(self.current_user) | ||
user_infos = mrd.select_table(table="users",column="*",condition="username",value=username) | ||
self.render("user.html", users = user_infos) | ||
|
||
在get()方法前面添加`@tornado.web.authenticated`,这是一个装饰器,它的作用就是完成tornado的认证功能,即能够得到当前合法用户。在原来的代码中,用`username = self.get_argument("user")`方法,从url中得到当前用户名,现在把它注释掉,改用`self.current_user`,这是和前面的装饰器配合使用的,如果它的值为假,就根据setting中的设置,寻找login_url所指定的目录(请关注下面对setting的配置)。 | ||
|
||
由于在index.py文件的set_current_user()方法中,是将user值转化为json写入cookie的,这里就得用`username = tornado.escape.json_decode(self.current_user)`解码。得到的username值,可以被用于后一句中的数据库查询。 | ||
|
||
application.py中的setting也要做相应修改: | ||
|
||
#!/usr/bin/env python | ||
# coding=utf-8 | ||
|
||
from url import url | ||
|
||
import tornado.web | ||
import os | ||
|
||
setting = dict( | ||
template_path = os.path.join(os.path.dirname(__file__), "templates"), | ||
static_path = os.path.join(os.path.dirname(__file__), "statics"), | ||
cookie_secret = "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=", | ||
xsrf_cookies = True, | ||
login_url = '/', | ||
) | ||
|
||
application = tornado.web.Application( | ||
handlers = url, | ||
**setting | ||
) | ||
|
||
与以前代码的重要区别在于`login_url = '/',`,如果用户不合法,根据这个设置,会返回到首页。当然,如果有单独的登录界面,比如是`/login`,也可以`login_url = '/login'`。 | ||
|
||
如此完成的是用户登录到网站之后,在页面转换的时候实现用户认证。 | ||
|
||
为了演示本节的效果,我对教程的源码进行修改。读者在阅读的时候,可以参照源码。 | ||
|
||
------ | ||
|
||
[总目录](./index.md) | [上节:用tornado做网站(5)](./307.md) | [下节:用tornado做网站(7)](./309.md) | ||
|
||
如果你认为有必要打赏我,请通过支付宝:**[email protected]**,不胜感激。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,121 @@ | ||
#This is for everyone. | ||
|
||
#From beginner to master. | ||
>In the begning when God created the heavens and the earth. the earth was a formless void and darkness covered the face of the deep, while a wind from God swept over the face of the waters. Then God said,"Let there be light"; and there was light. And God saw that the light was good; and God separated the light from the darkness. (GENESIS 1:1-4) | ||
#《零基础学python》(第二版):From beginner to master. | ||
|
||
#第壹季 基础 | ||
|
||
##第零章 预备 | ||
|
||
1. [关于python的故事](./01.md) | ||
2. [从小工到专家](./02.md) | ||
3. [安装python的开发环境](./03.md) | ||
4. [集成开发环境](./101.md)==>集成开发环境;python的IDE | ||
|
||
##第壹章 基本数据类型 | ||
|
||
1. [数和四则运算](./102.md)==>整数和浮点数;变量;整数溢出问题; | ||
2. [除法](./103.md)==>整数、浮点数相除;`from __future__ import division`;余数;四舍五入; | ||
3. [常用数学函数和运算优先级](./104.md)==>math模块,求绝对值,运算优先级 | ||
4. [写一个简单程序](./105.md)==>程序和语句,注释 | ||
5. [字符串(1)](./106.md)==>字符串定义,转义符,字符串拼接,str()与repr()区别 | ||
6. [字符串(2)](./107.md)==>raw_input,print,内建函数,原始字符串,再做一个小程序 | ||
7. [字符串(3)](./108.md)==>字符串和序列,索引,切片,基本操作 | ||
8. [字符串(4)](./109.md)==>字符串格式化,常用的字符串方法 | ||
9. [字符编码](./110.md)==>编码的基础知识,python中避免汉字乱码 | ||
10. [列表(1)](./111.md)==>列表定义,索引和切片,列表反转,元素追加,基本操作 | ||
11. [列表(2)](./112.md)==>列表append/extend/index/count方法,可迭代的和判断方法,列表原地修改 | ||
12. [列表(3)](./113.md)==>列表pop/remove/reverse/sort方法 | ||
13. [回顾列表和字符串](./114.md)==>比较列表和字符串的相同点和不同点 | ||
14. [元组](./115.md)==>元组定义和基本操作,使用意义 | ||
15. [字典(1)](./116.md)==>字典创建方法、基本操作(长度、读取值、删除值、判断键是否存在) | ||
16. [字典(2)](./117.md)==>字典方法:copy/deepcopy/clear/get/setdefault/items/iteritems/keys/iterkeys/values/itervalues/pop/popitem/update/has_key | ||
17. [集合(1)](./118.md)==>创建集合,集合方法:add/update,pop/remove/discard/clear,可哈希与不可哈希 | ||
18. [集合(2)](./119.md)==>不可变集合,集合关系 | ||
|
||
##第贰章 语句和文件 | ||
|
||
1. [运算符](./120.md)==>算数运算符,比较运算符,逻辑运算符/布尔类型 | ||
2. [语句(1)](./121.md)==>print, import, 赋值语句、增量赋值 | ||
3. [语句(2)](./122.md)==>if...elif...else语句,三元操作 | ||
4. [语句(3)](./123.md)==>for循环,range(),循环字典 | ||
5. [语句(4)](./124.md)==>并行迭代:zip(),enumerate(),list解析 | ||
6. [语句(5)](./125.md)==>while循环,while...else,for...else | ||
7. [文件(1)](./126.md)==>文件打开,读取,写入 | ||
8. [文件(2)](./127.md)==>文件状态,read/readline/readlines,大文件读取,seek | ||
9. [迭代](./128.md)==>迭代含义,iter() | ||
10. [练习](./129.md)==>通过四个练习,综合运用以前所学 | ||
11. [自省](./130.md)==>自省概念,联机帮助,dir(),文档字符串,检查对象,文档 | ||
|
||
##第叁章 函数 | ||
|
||
1. [函数(1)](./201.md)==>定义函数方法,调用函数方法,命名方法,使用函数注意事项 | ||
2. [函数(2)](./202.md)==>函数返回值,函数文档,形参和实参,命名空间,全局变量和局部变量 | ||
3. [函数(3)](./203.md)==>收集参数:`*`和`**`,及其逆过程,复习参数知识 | ||
4. [函数(4)](./204.md)==>递归和filter、map、reduce、lambda、yield | ||
5. [函数练习](./205.md)==>解一元二次方程,统计考试成绩,找素数 | ||
|
||
#第贰季 进阶 | ||
|
||
##第肆章 类 | ||
|
||
1. [类(1)](./206.md)==>类的初步认识和基本概念理解:问题空间、对象、面向对象、类和实例化类 | ||
2. [类(2)](./207.md)==>新式类和旧式类,类的命名,构造函数,实例化及方法和属性,self的作用 | ||
3. [类(3)](./208.md)==>类属性和实例属性,类内外数据流转,命名空间、作用域 | ||
4. [类(4)](./209.md)==>继承,多重继承,super函数 | ||
5. [类(5)](./210.md)==>静态方法和类方法,两者的区别,类的文档 | ||
6. [多态和封装](./211.md)==>多态,封装和私有化 | ||
7. [特殊方法(1)](./212.md)==>`__dict__`和`__slots__` | ||
8. [特殊方法(2)](./213.md)==>`__getattr__`,`__setattr__`以及查找属性顺序 | ||
9. [迭代器](./214.md)==>迭代器方法`__iter__`,`netx()` | ||
10. [生成器](./215.md)==>生成器定义,yield,生成器方法 | ||
|
||
##第伍章 错误和异常 | ||
|
||
1. [错误和异常(1)](./216.md)==>什么是错误和异常,常见异常类型,处理异常(try...except...) | ||
2. [错误和异常(2)](./217.md)==>处理多个异常,else子句,finally子句 | ||
3. [错误和异常(3)](./218.md)==>assert断言,异常小结 | ||
|
||
##第陆章 模块 | ||
|
||
1. [编写模块](./219.md)==>模块是程序,模块的位置 | ||
2. [标准库(1)](./220.md)==>引用模块的方式,dir()查看属性和方法,模块文档和帮助 | ||
3. [标准库(2)](./221.md)==>sys,copy | ||
4. [标准库(3)](./222.md)==>os模块:操作文件、目录,查看修改属性,执行系统命令,打开网页 | ||
5. [标准库(4)](./223.md)==>堆的基本知识,heapq模块,deque模块 | ||
6. [标准库(5)](./224.md)==>calendar模块、time模块、datetime模块 | ||
7. [标准库(6)](./225.md)==>urllib模块、urllib2模块 | ||
8. [标准库(7)](./226.md)==>xml.etree.ElementTree模块:遍历查询、增删改查xml,应用实例 | ||
9. [标准库(8)](./227.md)==>json模块:dumps(),loads(),dump(),load(),自定义类型数据的json编码和解码 | ||
10. [第三方库](./228.md)==>第三方库的模块安装方法,以requests模块为例说明 | ||
|
||
##第柒章 保存数据 | ||
|
||
1. [将数据存入文件](./229.md)==>pickle模块,shelve模块 | ||
2. [MySQL数据库(1)](./230.md)==>MySQL概况,安装,python连接MySQL模块和方法 | ||
3. [MySQL数据库(2)](./231.md)==>连接对象方法,游标对象方法:数据库的增删改查基本操作 | ||
4. [MongoDB数据库](./232.md)==>mongodb的安装启动,pymongo模块:连接客户端,数据库的增删改查操作 | ||
5. [SQLite数据库](./233.md)==>通过sqlite3模块操作SQLite数据库:连接对象方法,游标对象方法,数据库增删改查 | ||
6. [电子表格](./234.md)==>python操作Excel文件的第三方库openpyxl使用方法,以及其它与Excel相关的第三方库 | ||
|
||
#第叁季 实战 | ||
|
||
0. [引](./300.md) | ||
|
||
##第捌章 用Tornado做网站 | ||
|
||
1. [为做网站而准备](./301.md)==>开发框架,python的常用web框架,tornado框架介绍和安装 | ||
2. [分析Hello](./302.md)==>发布tornado做的网站,并剖析基本结构 | ||
3. [用tornado做网站(1)](./303.md)==>网站的基本结构,一个基于tornado框架的网站架子 | ||
4. [用tornado做网站(2)](./304.md)==>前端模板,静态文件引入 | ||
5. [用tornado做网站(3)](./305.md)==>ajax传输数据,get_argument()接收数据,验证用户名和密码 | ||
6. [用tornado做网站(4)](./306.md)==>render()方法使用,模板语法,转义(自动转义,不转义) | ||
7. [用tornado做网站(5)](./307.md)==>模板继承和块语句,CSS文件,cookie以及XSRF安全防护方法 | ||
|
||
##第五部分:科学计算 | ||
|
||
##附:网络文摘 | ||
|
||
1. [如何成为python高手](./n001.md) | ||
2. [ASCII、Unicode、GBK和UTF-8字符编码的区别联系](./n002.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters