Tronado's web application security (cookie and CSRF/XSRF)
Security cookies is one of the security precautions for web applications. Cooks in browsers store user's personal information, including some important sensitive information. If some malicious scripts get or even modify user's cookies information, user's information will not be secured, so user's cookies should be protected. Tornado's secure cookies can encrypt cookies signatures safely. It has been checked whether cookies have been modified, because malicious scripts do not know the security key, so they can not be modified (but malicious scripts can still intercept cookies to "impersonate" users, just can not modify cookies, which is another security hazard. This article does not discuss this point).
Tornado's get_secure_cookie() and set_secure_cookie() can safely retrieve and send browser cookies to prevent malicious modifications in browsers, but to use this function, cookie_secret must be set in the settings of tornado.web.Application, whose value is a unique random string (such as: base64.b64 encode (uuid.uuid4(). bytes + uuid.uuid.uui). D4 (). bytes) can produce a unique random string.
CSRF or XSRF, or cross-site request forgery, is a security vulnerability involved in web applications. It exploits a security vulnerability of browsers: browsers allow malicious attackers to inject scripts into victim websites so that unauthorized requests represent a logged-in user. That is, other people can "impersonate" you to do something, and the server will think that you do it.
In order to prevent XSRF attacks, we should pay attention to: first, developers need to use POST method when considering some important requests; second, Tornado's function to prevent forgery of POST (this function is a strategy, tornado also implements this strategy), that is, to include a parameter value (hidden HTML form element value) and stored cookie value in each request, if both of them.( A matching token proves that the request is valid. When an untrustworthy site does not have access to cookie data, it can no longer request the token cookie value, and naturally cannot send valid requests. To use this function in tornado, you need to set xsrf_cookies in settings of tornado.web.Application with the value of True, and you must include the xsrf_form_html() function in the HTML form to form a cookie token.
User authentication of tornado can use the decorator @tornado.web.authenticated. When using this decorator, it should be noted that: (1) the get_current_user() method must be rewritten, and the returned value will be assigned to self.current_user; and (2) the bool value of self.current_user will be checked whether it is False (default is None) before the decorated method is executed, and if it is False, it will be redirected to tornado.web. The URL specified by login_url in application settings, and (3) the URL of login_url in tornado.web.Application settings are needed so that the user can redirect to the URL before verifying self. current_user. (4) When Tornado builds a redirect URL, it also adds a next parameter to the query string, whose value is the URL before redirection. You can use statements such as self.redirect(self.get_argument('next','/') to return to the original page after the user has successfully verified it.
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 """Override this method, and the returned value is assigned to self.current_user""" 19 return self.get_secure_cookie('username') # Obtain cookies in username Value 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')) # In the request username Assign value to cookie Medium username 28 self.redirect('/') 29 30 31 class HomeHandler(BaseHandler): 32 @tornado.web.authenticated # You must rewrite the method to use this decorator get_current_user 33 def get(self): 34 """cover@tornado.web.authenticated Decoration methods will be checked before they are implemented. self.current_user Of bool Is the value of False,Not for False Only then will this method be executed""" 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') # clear cookies Middle name is username Of 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), # Set up cookies Security, value is a unique random string 51 'xsrf_cookies': True, # Set up xsrf Safety, set this must be after HTML The form contains xsrf_form_html() 52 'login_url': '/login' # When being@tornado.web.authenticated Inspection of Decorator Packing Method self.current_user Of bool The value is False When you do, you redirect to this 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()%}<! - This is actually a hidden < input > element that defines the value of'_xsrf', checks POST requests to prevent forgery of cross-site requests - >. 10 Username: <input type="text" name="username" /> 11 <input type="submit" value="Log In" /> 12 </form> 13 </body> 14 </html>