01 cookie
在上节,我们简单了解了登录过程,但是很明显,每次都需要登录,但是在平常逛网站的只需要登录一次,那么网站是如何记录登录信息的呢?
有没有什么办法可以让浏览器记住登录信息,下次再次打开的时候,可以自动登录呢?
设置 cookie
self.set_cookie('cookie_test','this_is_test')#默认过期时间是浏览器关闭会话时 self.set_cookie('cookie_test1','this_is_test',expires=time.time()+60)#设置过期时间为60秒 self.set_cookie('cookie_test2','this_is_test',expires_days=1)#设置过期时间为一天 self.set_cookie('cookie_test3','this_is_test',path='/') #默认目录 self.set_cookie('cookie_test4','this_is_test',httponly=True) #设置路径,设置 js 不可以获取cookie self.set_cookie('cookie_test5','this_is_test',max_age=120,expires=time.time()+60)#max_age 优先级高,过期时间变为120秒。
self.set_secure_cookie('cookie_test6','this_is_test')#设置加密cookie,需要设置 application 的 cookie_secret 参数
获取 cookie
self.get_cookie('cookie_test') # 获取一般的 cookie
self.get_secure_cookie('cookie_test6') #获取加密 cookie
02 登录验证
继续回到上个问题,我们希望用户只需要在第一次登录的时候输入用户名和密码,之后可以自动登录,不需要再次输入用户名和密码,也就是说在用户第二次访问的时候,服务器能够自动的验证用户登录信息,那么如何实现自动验证的功能呢?
第一步:导入装饰器
fromtornado.web import authenticated
第二步:声明 BaseHandler
class BaseHandler(tornado.web.RequestHandler): def get_current_user(self): current_user = self.get_secure_cookie('ID') if current_user: return current_user return None
第三步:配置登录路由
login_url='/login',
第四步:装饰需要验证的请求
class BuyHandler(BaseHandler): @authenticated def get(self): self.write('BuyHandler')
在完成登录之后,再来看看,我们从一个路由跳转到登录页面之后,再完成登录之后,该如何跳转到之前的页面呢?
第一步:获取之前路由
class LoginHandler(BaseHandler): def get(self): nextname = self.get_argument('next','') self.render('01in_out.html',nextname=nextname)
在使用 authenticated之后,如果验证不成功,会自动跳转到登录路由,并且在 URL 后面加上 next 参数,next 参数的参数值就是之前的路由
第二步:修改模板文件
‘<form method="post" action="/login?next={{ nextname }}">’ 在模板中添加 next 参数,并且参数值为之前的路由
第四步:修改post方法
def post(self, args, kwargs): nextname = self.get_argument('next', '') user = self.get_argument('name', '') username = User.by_name(user) passwd = self.get_argument('password', '') if username and passwd == username.password: self.set_secure_cookie('ID', username.username, max_age=100) self.redirect(nextname) else: self.render('01in_out.html', nextname=nextname)
获取之前的页面的路由,当登录验证通过之后,设置加密的 cookie ,并跳转到之前的路由
03 session
通过刚才的学习,可以用了解到 cookie中的信息可以用来保存用户的登录信息,但是coolkie是很容易被拦截的,所有其中必定不能有用户的任何私密信息,那么又有什么办法可以让服务器保存用户的登录信息,但是cookie中又不会有用户的任何信息呢?
第一步:安装模块
pip install pycket
pip install redis
第二步:导入模块
from pycket.session import SessionMixin
第三步:继承SessionMixin
class BaseHandler(tornado.web.RequestHandler, SessionMixin):
第四步:在application 中添加配置
pycket={ 'engine': 'redis', 'storage': { 'host': 'localhost', 'port': 6379, 'db_sessions': 5, 'db_notifications': 11, 'max_connections': 2 31, }, 'cookies': { 'expires_days': 30, 'max_age': 100 }, },
配置 redis 的相关信息
配置 cookie 的过期时间
第五步:改设置cookie为设置session
self.session.set('user',username[0].username)
第六步:改获取cookie为获取session
current_user = self.session.get('user')
04 XSRF
使用session可以保证用户信息不被cookie泄漏,那如果如果攻击者不想获取用户信息,只是在提交form 表单时攻击,该怎么防范呢?
XSRF 跨站伪造请求
模板添加
{% module xsrf_form_html()%}
Tornado 有内建的 XSRF 的防范机制,要使用此机制,只需要在模板中添加如上代码