cookiehtml
在上節課,咱們簡單瞭解了登陸過程,可是很明顯,每次都須要登陸,可是在日常逛網站的只須要登陸一次,那麼網站是如何記錄登陸信息的呢?python
有沒有什麼辦法可讓瀏覽器記住登陸信息,下次再次打開的時候,能夠自動登陸呢?web
設置cookie與獲取cookieredis
import sys import time import tornado.web import tornado.ioloop import tornado.httpserver import tornado.options from tornado.web import RequestHandler from tornado.options import define,options import util.ui_modules import util.ui_methods # import time from data.connect import session from data.user_modules import UserDetails, User define('port',default=8080,help='run server',type=int) class MainHandler(RequestHandler): def get(self): self.write('cookie') self.set_cookie('cookie_test','aqweqwas') self.set_cookie('cookie_test2','aqweqwas2',expires=time.time()+60) #設置過時時間 self.set_cookie('cookie_test3','aqweqwas3',expires_days=1) #設置過時天數 self.set_cookie('cookie_test4','aqweqwas4',path='/') #設置cookie路徑 self.set_cookie('cookie_test5','aqweqwas5',httponly=True) #設置後js代碼獲取不到此cookie值 self.set_cookie('cookie_test6','aqweqwas6',max_age=120,expires=time.time()+60) #設置過時時間max_age的優先級大於expires self.set_secure_cookie('cookie_test7','aqweqwas7',max_age=120,expires=time.time()+60) #設置加密cookies class GetHandler(RequestHandler): def get(self): self.write('get_cookie') self.write('<br>') cookie_name = self.get_cookie('cookie_test4') cookie_name2 = self.get_secure_cookie('cookie_test7') self.write(cookie_name) self.write('<br>') self.write(cookie_name2) application = tornado.web.Application( handlers=[ (r'/',MainHandler), (r'/get',GetHandler), ], debug=True, template_path = 'templates', static_path='static', # autoescape = None, #全局取消轉義 ui_methods=util.ui_methods, ui_modules=util.ui_modules, cookie_secret ='qwe123', #cookie加鹽 ) if __name__ == '__main__': tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(application) http_server.listen(options.port) tornado.ioloop.IOLoop.current().start()
登陸驗證:跨域
第一步:導入裝飾器瀏覽器
from tornado.web import authenticated
第二步:聲明 BaseHandler服務器
class BaseHandler(RequestHandler): def get_current_user(self): current_user = self.get_secure_cookie('user_ID') if current_user: return current_user return None
第三步:配置登陸路由cookie
login_url = '/login'
第四步:裝飾須要驗證的請求session
class BuyHandler(BaseHandler): @authenticated def get(self): self.write('嗨,小可愛!')
在完成登陸以後,再來看看,咱們從一個路由跳轉到登陸頁面以後,再完成登陸以後,該如何跳轉到以前的頁面呢?app
第一步:獲取以前路由
class LoginHandler(BaseHandler): def get(self): next_name = self.get_argument('next','') self.render('in_out.html',nextname=next_name)
在使用 authenticated 以後,若是驗證不成功,會自動跳轉到登陸路由,而且在 URL 後面加上 next 參數,next 參數的參數值就是以前的路由
第二步:修改模板文件
<form method="post" action="/login?next={{ nextname }}">
在模板中添加 next 參數,而且參數值爲以前的路由
第三步:修改post方法
def post(self): '''驗證邏輯''' user = self.get_argument('name',None) password = self.get_argument('password',None) next_name = self.get_argument('next','') print(next_name) # username = session.query(User).filter(User.username == user).first() username = User.get_name(user) print(username) if username and password == username.password: #若是判斷用戶能夠登陸,咱們設置這樣一個加密的cookie進去 self.set_secure_cookie('user_ID',user) self.redirect(next_name) else: self.write('登陸失敗')
獲取以前的頁面的路由
當登陸驗證經過以後,設置加密的 cookie ,並跳轉到以前的路由
完整的python代碼與模板html代碼以下:
import sys import time import tornado.web import tornado.ioloop import tornado.httpserver import tornado.options from tornado.web import RequestHandler,authenticated from tornado.options import define,options import util.ui_modules import util.ui_methods # import time from data.connect import session from data.user_modules import UserDetails, User define('port',default=8080,help='run server',type=int) class BaseHandler(RequestHandler): def get_current_user(self): current_user = self.get_secure_cookie('user_ID') if current_user: return current_user return None class BuyHandler(BaseHandler): @authenticated def get(self): self.write('嗨,小可愛!') #第一,若是有參數next,確定是沒登陸的時候 #沒登陸,會跳轉到/login,app裏面設置的 #在login裏面,form表單沒提交以前,get裏面獲取一下這個值 #在獲取出來以後,吧這個值傳到post請求裏面 #post獲取這個值,此值就是一個url #直接跳轉到此url class LoginHandler(BaseHandler): def get(self): next_name = self.get_argument('next','') self.render('in_out.html',nextname=next_name) def post(self): '''驗證邏輯''' user = self.get_argument('name',None) password = self.get_argument('password',None) next_name = self.get_argument('next','') print(next_name) # username = session.query(User).filter(User.username == user).first() username = User.get_name(user) print(username) if username and password == username.password: #若是判斷用戶能夠登陸,咱們設置這樣一個加密的cookie進去 self.set_secure_cookie('user_ID',user) self.redirect(next_name) else: self.write('登陸失敗') application = tornado.web.Application( handlers=[ (r'/buy',BuyHandler), (r'/login',LoginHandler), ], debug=True, template_path = 'templates', static_path='static', # autoescape = None, #全局取消轉義 ui_methods=util.ui_methods, ui_modules=util.ui_modules, cookie_secret ='qwe123', #cookie加鹽 login_url = '/login' ) if __name__ == '__main__': tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(application) http_server.listen(options.port) tornado.ioloop.IOLoop.current().start()
in_out.html代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>tornado</title> </head> <body> <form method="post" action="/login?next={{ nextname }}"> <p>用戶名<input type="text" name="name"></p> <p>密碼<input type="password" name="password"></p> <input type="submit"> </form> </body> </html>
session
經過剛纔的學習,能夠用瞭解到 cookie 中的信息能夠用來保存用戶的登陸信息,可是coolkie 是很容易被攔截的,全部其中一定不能有用戶的任何私密信息,那麼又有什麼辦法可讓服務器保存用戶的登陸信息,可是cookie中又不會有用戶的任何信息呢?
第一步:安裝模塊
pip install pycket #tornado中用於鏈接redis的模塊
pip install redis
第二步:導入模塊
from pycket.session import SessionMixin
第三步:繼承SessionMixin
class BaseHandler(tornado.web.RequestHandler, SessionMixin):
第四步:在application 中添加配置
配置 redis 的相關信息
配置 cookie 的過時時間
pycket = { 'engine':'redis', 'storage':{ 'host':'localhost', 'port':6379, 'db_sessions':5, 'max_connections':2**10, }, 'cookies':{ 'expires_days':7 } }
第五步:改設置cookie爲設置session
self.session.set('user_ID',user)
第六步:改獲取cookie爲獲取session
current_user = self.session.get('user_ID')
完整代碼以下:
import sys import time import tornado.web import tornado.ioloop import tornado.httpserver import tornado.options from tornado.web import RequestHandler,authenticated from tornado.options import define,options from pycket.session import SessionMixin import util.ui_modules import util.ui_methods # import time from data.connect import session from data.user_modules import UserDetails, User define('port',default=8080,help='run server',type=int) class BaseHandler(RequestHandler,SessionMixin): def get_current_user(self): current_user = self.session.get('user_ID') if current_user: return current_user return None class BuyHandler(BaseHandler): @authenticated def get(self): self.write('嗨,小可愛!') #第一,若是有參數next,確定是沒登陸的時候 #沒登陸,會跳轉到/login,app裏面設置的 #在login裏面,form表單沒提交以前,get裏面獲取一下這個值 #在獲取出來以後,吧這個值傳到post請求裏面 #post獲取這個值,此值就是一個url #直接跳轉到此url class LoginHandler(BaseHandler): def get(self): next_name = self.get_argument('next','') self.render('in_out.html',nextname=next_name) def post(self): '''驗證邏輯''' user = self.get_argument('name',None) password = self.get_argument('password',None) next_name = self.get_argument('next','') print(next_name) # username = session.query(User).filter(User.username == user).first() username = User.get_name(user) print(username) if username and password == username.password: #若是判斷用戶能夠登陸,咱們設置這樣一個加密的cookie進去 # self.set_secure_cookie('user_ID',user) self.session.set('user_ID',user) self.redirect(next_name) else: self.write('登陸失敗') application = tornado.web.Application( handlers=[ (r'/buy',BuyHandler), (r'/login',LoginHandler), ], debug=True, template_path = 'templates', static_path='static', # autoescape = None, #全局取消轉義 ui_methods=util.ui_methods, ui_modules=util.ui_modules, cookie_secret ='qwe123', #cookie加鹽 login_url = '/login', pycket = { 'engine':'redis', 'storage':{ 'host':'localhost', 'port':6379, 'db_sessions':5, 'max_connections':2**10, }, 'cookies':{ 'expires_days':7 } } ) if __name__ == '__main__': tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(application) http_server.listen(options.port) tornado.ioloop.IOLoop.current().start()
XSRF:防止跨域請求僞造
使用session能夠保證用戶信息不被cookie泄漏,那若是若是攻擊者不想獲取用戶信息,只是在提交 form 表單時攻擊,該怎麼防範呢?
模板添加
{% module xsrf_form_html() %}
代碼以下:
<body> {% module xsrf_form_html() %} <form method="post" action="/login?next={{ nextname }}"> <p>用戶名<input type="text" name="name"></p> <p>密碼<input type="password" name="password"></p> <input type="submit"> </form> </body>
Tornado 有內建的 XSRF 的防範機制,要使用此機制,只須要在模板中添加如上代碼
頁面效果顯示:
生成一段關於xsrf的隨機字符串,防止僞造