tornado 之authenticated和session 简单登录


1.登录检查(装饰器的使用)

我们登录的时候需要验证,但是如果有很多地方需要验证,这个时候就会出现很多重复代码的情况,这个时候我们需要一个不改变函数运行,又能给函数加上验证过程方法,很明显,我们可以使用装饰器来达到这个功能,代码如下:

def auth(fun):
    def wrapper(self,*args,**kwargs):
        id = self.get_secure_cookie('ID')
        if id:
            return fun(self,*args,**kwargs)
        else:
            self.redirect('/login')
    return wrapper

#定义好装饰器之后,就可以直接去修饰需要验证的方法  

class IndexHandler(BaseHandler):
    @auth
    def get(self):
        self.write('登录成功---index')

使用装饰器可以很方便我们去做登录检查,可以节省出大量的代码,增加程序的可读性和程序整体的美观。

2.authenticated

虽然我们自己可以做这个登录检查,但是在tornado内部给我们提供了一个内置的装饰器`authenticated`这个可以帮我们自动的进行登录验证,`authenticated`可以省去我们自己重复造轮子的过程,但是在使用的时候需要注意几点:

# Application中添加配置
login_url='/login',

# 重写 get_current_user 方法
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
# 装饰需要验证的方法      
@authenticated     

有些时候我们需要跳转到之前的页面怎么做呢?当我们使用`authenticated`的时候我们可以十分方便的做这件事情。我们观察跳转之后的url就可以发现,如果是使用`authenticated`装饰器装饰之后,而跳转到登录页面之后,在登录页面的url中,可以看到最后面会添加上一个next参数,这个就是我们刚才跳转的路由,通过这个参数,我们就可以很方便的跳转回之前的的路由,具体实现如下:

class LoginHandler(BaseHandler):
    def get(self):
        nextname = self.get_argument('next','')
        self.render('authenticated.html',nextname=nextname)
    def post(self):
        nextname = self.get_argument('next', '')
        username = self.get_argument('name','')
        username = User.by_name(username)
        passwd = self.get_argument('password', '')
        print(username)
        if username and username[0].password == passwd:
            self.set_secure_cookie('ID',username[0].username,max_age=100)
            self.redirect(nextname)
        else:
            self.render('authenticated.html',nextname=nextname)

页面代码做如下的改变就行:

<form method="post" action="/login?next={{nextname}}">
    <p>用户名<br><input type="text" name="name"></p>
    <p>密码<br><input type="text" name="password"></p>
    <input type="submit">
</form>

配合使用模板的传参,可以很方便的进行跳转。

3.session

cookie中不能存放存放用户的敏感信息,那么cookie里面就只能存放一些随机的字符串,但是如果这样的话,那么服务器端又怎样知道是那个用户呢?

我们可以建立一个会话来做这件事情,这个会话里面会存储随机字符串和可以唯一确定用户的信息。

由于tornado没有内置session模块,所以使用pycket这个模块中封装好的session模块来,要想使用首先要安装:

pip install pyckey
pip install redis

安装好之后就可以使用了,使用很简单,注意一下几点:

from pycket.session import SessionMixin

# 1.在Application添加 pycket 的配置
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
  },
},

# 2.改 self.set_secure_cookie 为 self.session.set
# self.set_secure_cookie('ID',username[0].username,max_age=100)
self.session.set('user',username[0].username)

# 3.改 self.get_secure_cookie 为 self.session.get
# current_user = self.get_secure_cookie('ID')
current_user = self.session.get('user')

以上就可以使用`session`了,这个`session`的工作原理是如下:

1. 使用`set`方法,为输入的用户信息生成一串随机字符串
2. 将这个字符串和对应的用户信息做成键值对,放到`redis`数据库中
3. 将字符串处理之后放入到`cookie`中,发送给浏览器
4. 浏览器请求时将`cookie`中的信息发送到服务器,`tornado`接受到之后解析出来,去`redis`查找,找到就验证成功

使用`session`有如下好处:

1. 可以不要在`cookie`中存放敏感信息
2. 减少数据传输需要的时间
3. 减少加密解密的时间

`session`的使用很简单,但是安全性会有一个很大的提升,因此使用非常多,一定要掌握使用方法。

4.跨站防伪造请求的防范

跨站伪造请求(Cross-site request forgery)](https://en.wikipedia.org/wiki/Cross-site_request_forgery), 简称为 `XSRF`,是个性化 Web 应用中常见的一个安全问题。前面的链接也详细讲述了` XSRF `攻击的实现方式。

当前防范` XSRF` 的一种通用的方法,是对每一个用户都记录一个无法预知的` cookie `数据,然后要求所有提交的请求中都必须带有这个` cookie `数据。如果此数据不匹配 ,那么这个请求就可能是被伪造的。

`Tornado `有内建的 `XSRF `的防范机制,要使用此机制,只需要在模板中添加如下代码:

<form method="post" action="/login?next={{nextname}}">
    {% module xsrf_form_html() %}   <!--添加这行代码就可以了-->
    <p>用户名<br><input type="text" name="name"></p>
    <p>密码<br><input type="text" name="password"></p>
    <input type="submit">

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM