文/唐志峰
在公司项目中之后需要运用用户验证,而且是头次使用Tornado,所以记录下,Tornado的用户验证,本篇主要来自Tornado官方文档.
关键点
set_secure_cookie函数
006tKfTcgy1fo82wof2nyj30xk0i8q3q.jpg这里强调了我们需要在setting中指定一个cookie_secret
,上面还指定了expires_days
同时还有max_age_days
.
可以通过这两个属性调整cookie的有效期.
get_current_user函数
我们重写了get_current_user
函数,这个函数的作用是确定当前用户.
Override to determine the current user from, e.g., a cookie.
This method may not be a coroutine.
对该函数的官方注释.
大家看下面的代码:
def get_current_user(self):
return self.get_secure_cookie("user") #该函数用于查看是否验证 name 中的cookie
get_secure_cookie函数
返回对应的cookie.
Returns the given signed cookie if it validates, or None.
The decoded cookie value is returned as a byte string (unlike
get_cookie
).
该函数与get_current_user
对应,当我们设置了self.set_secure_cookie("user", accout)
上面的get_current_user
函数返回就会变成之前我们传入的accout
.用来给get_current_user
来确定当前的用户.
@tornado.web.authenticated
006tKfTcgy1fo83126g7sj30xi0pijsu.jpg这是它的源码,如果我们没有获取self.current_user,同时我使用的是get,head方法,我们就会跳转到我们之前设置的'login_url':'/login'
.
例子
下面是一个很简单的html
文件,使用ajax-post
请求去验证用户名与密码.每次验证都重定向请求http://127.0.0.1:8080/
如果它在后端没有验证成功就会被后台重定向进入http://127.0.0.1:8080/login
然后反反复复.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>登录</title>
<script type="text/javascript" src="https://cdn.bootcss.com/jquery/2.1.1-rc2/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('#login').click(function(){
$.ajax({
type: 'POST',
async: false,
url: 'http://127.0.0.1:8080/login',
data: {user_name:$("input[id='user_name']").val(),user_pass:$("input[id='user_pass']").val()},
success: function (data){
window.location.replace("http://127.0.0.1:8080/");
}
}
)
})
});
</script>
</head>
<body>
用户名: <input type="text" name="user_name" id="user_name"><br>
密码: <input type="password" name="user_pass" id="user_pass"><br>
<button id="login">登录</button>
</body>
</html>
后台代码,代码中主要还是我之前说的那些.
'''
@Author: 唐志峰
@Function: Tornado后台
@Time: 2018/2/7 09:32
'''
import os
import tornado
import tornado.web
import tornado.ioloop as ioloop
import tornado.httpserver as httpserver
from modes.user_operation import user_login # 这个为验证用户的函数
class BaseHandle(tornado.web.RequestHandler):
# 覆盖这个函数用来确定当前用户
def get_current_user(self):
return self.get_secure_cookie("user") #该函数用于查看是否验证 name 中的cookie
class Login(BaseHandle):
def get(self):
self.render('login.html')
def post(self):
accout=self.get_argument('user_name')
password=self.get_argument('user_pass')
login_result=user_login(accout,password)
if not login_result:
self.redirect("http://127.0.0.1:8080/login")
else:
self.set_secure_cookie("user", accout)
self.redirect("http://127.0.0.1:8080/")
def set_default_headers(self):
self.set_header("Access-Control-Allow-Origin", "*")
self.set_header("Access-Control-Allow-Headers", "x-requested-with")
self.set_header("Access-Control-Allow-Methods", "POST,GET,OPTIONS")
class Main(BaseHandle):
@tornado.web.authenticated
def get(self):
name = tornado.escape.xhtml_escape(self.current_user) # 获得用户身份信息 self.current_user,默认为None
self.write("Hello, " + name)
def set_default_headers(self):
self.set_header("Access-Control-Allow-Origin", "*")
self.set_header("Access-Control-Allow-Headers", "x-requested-with")
self.set_header("Access-Control-Allow-Methods", "POST,GET,OPTIONS")
def make_app():
settings = {
'cookie_secret':'asdfkljlkj2l382432lk',
'login_url':'/login',
'static_path':os.path.join(os.path.dirname(__file__),'static'),
'template_path':os.path.join(os.path.dirname(__file__),'templates'),
}
application = tornado.web.Application([
(r'/login',Login),
(r'/',Main)
],**settings)
http_server = httpserver.HTTPServer(application)
http_server.listen(8080)
ioloop.IOLoop.current().start()
def main():
make_app()
if __name__ == '__main__':
main()
说明
-
from modes.user_operation import user_login
:这个是我写的一个登录接口,通过数据库进行验证. -
@tornado.web.authenticated
这个装饰器很好用,可以在每一次请求中都加入这个模块,这样我就可以验证用户是否是登录的状态. -
BaseHandler
:该类为基类,因为他重新了get_current_user
方法,在你的应用程序中实现用户认证,必须重新该方法. - settings中必须设置
cookie_secret
,否则会出现错误.
网友评论