关于用户的登录状态,一部分的应用程序是采用session实现的。

HTTP是一个无状态协议,用户的每次请求都是相互独立的,HTTP本身意识不到用户是否登录。

很多web框架选择将session存放在cookies中,本节我们也是这样实现:

import tornado.ioloop
import tornado.web class BaseHandler(tornado.web.RequestHandler):
def get_current_user(self):
return self.get_secure_cookie("user") class MainHandler(BaseHandler):
def get(self):
if not self.current_user:
self.redirect("/login")
return
name = tornado.escape.xhtml_escape(self.current_user)
self.write("Hello, " + name) class LoginHandler(tornado.web.RequestHandler):
def get(self):
self.render("login.html")
def post(self):
self.set_secure_cookie("user", self.get_argument("name"))
self.redirect("/") application = tornado.web.Application([
(r"/", MainHandler),
(r"/login", LoginHandler)
], cookie_secret="61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=") if __name__ == '__main__':
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()

这里的核心便是LoginHandler类,他的get方法对于HTTP的GET请求,返回一个表单,对于post方法,则认为是用户的登录动作。

登录页面login.html代码如下:

<html>
<head>
<title>Login</title>
</head>
<body>
<form action="/login" method="post" accept-charset="utf-8">
<input type="text" name="name" value="your username"><br>
<input type="submit" value="submit">
</form>
</body>
</html>

这里处理实际登录的逻辑是,在cookies中存入相应的数据。

这样,我们检测用户是否登录,只需检测cookies即可,这是BaseHandler的核心逻辑,它重写了父类的get_current_user方法。

注意MainHandler的逻辑:

如果用户没有登录,那么跳转到登录页面。

如果用户登录,那么打印出欢迎的语句。

采用装饰器

 

这里的检查登录的代码,我们可以使用闭包写一个装饰器,这样可以减少代码的冗余:

login_url = "login.html"

def require_login():
def temp(func):
def wrapped(self, *args, **kargs):
if not self.current_user:
self.redirect(login_url)
return
return wrapped
return temp

这样我们在MainHandler中只需要采用装饰器修饰即可:

class MainHandler(BaseHandler):
@require_login()
def get(self):
name = tornado.escape.xhtml_escape(self.current_user)
self.write("Hello, " + name)

 

采用框架提供的装饰器

 

MainHandler需要检测用户是否登录,我们可以采用装饰器@tornado.web.authenticated来帮助我们完成这一目标,而不需要手工写出检测的代码。

import tornado.ioloop
import tornado.web class BaseHandler(tornado.web.RequestHandler):
def get_current_user(self):
return self.get_secure_cookie("user") class MainHandler(BaseHandler):
@tornado.web.authenticated
def get(self):
name = tornado.escape.xhtml_escape(self.current_user)
self.write("Hello, " + name) class LoginHandler(tornado.web.RequestHandler):
def get(self):
self.render("login.html")
def post(self):
self.set_secure_cookie("user", self.get_argument("name"))
self.redirect("/") settings = {
"cookie_secret": "61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o",
"login_url": "/login",
} application = tornado.web.Application([
(r"/", MainHandler),
(r"/login", LoginHandler)
], **settings) if __name__ == '__main__':
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()

很显然,@tornado.web.authenticated这个装饰器的功能与我们编写的require_login功能相似。

另外,在自己编写的装饰器中,我们将login_url单独做成了变量,保证可配置性,所以这里我们也需要配置login_url选项。

最新文章

  1. mysql主从配置
  2. Ionic Lab下载地址
  3. 使用putty与SSHSecureShellClient登录远程服务器完成与本地Git项目的同步
  4. JAVA基础学习day19--IO流一、FileWrite与FileReader
  5. Android渗透测试Android渗透测试入门教程大学霸
  6. 十大Intellij IDEA快捷键(转)(2015年06月15日)
  7. 03_HttpClient_Post请求
  8. VS项目属性配置实验过程
  9. html 细线表格
  10. Android反编译工具
  11. 关于js基本类型与引用类型(堆内存、栈内存的理解)
  12. extjs [1]
  13. Ubuntu 如何更换阿里源
  14. Thrift实现C#调用Java开发步骤详解
  15. [luogu5048] [Ynoi2019模拟赛] Yuno loves sqrt technology III
  16. BZOJ5329: [SDOI2018]战略游戏——题解
  17. C语言语法目录二
  18. 列表推导式对比For循环执行效率
  19. VC解决方案,项目,开发一段时间启动调试很慢,半天才开始链接
  20. JS调用百度地图。

热门文章

  1. DRF-自动生成接口文档
  2. python中的迭代器详解
  3. python笔记-邮件发送(smtplib)【转载】
  4. 在一个ros包下怎么使用另外一个自定义ros包里的message
  5. 转载 Ofbiz 入门教程
  6. cat命令和tac命令
  7. 前端读者 | 分分钟让你理解HTTPS
  8. 记一次对python反弹shell的分析
  9. POJ 2492 A Bug&#39;s Life【并查集高级应用+类似食物链】
  10. 使用selenium模拟知网登录