.Tang

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

通过redis的seesion对cookie信息加密  --- 防止cookie记录的用户信息泄露

import tornado.ioloop
import tornado.web

from data.table_1 import User
from tornado.web import authenticated  # 装饰器判断是否登录,否者就跳转到登陆页面。通过application配置跳转路径

from pycket.session import SessionMixin  # 设置redis加密cookie的一个类,BaseHandler继承

import tornado.options
import tornado.httpserver
from tornado.options import define, options


define('port',default=8000, help='run port', type=int)
define('version', default=0.1, help='version', type=str)

  # 装饰器authenticated需要的Base类       通过redis加密需要继承这个SessionMixin
class BaseHandler(tornado.web.RequestHandler, SessionMixin):  
    def get_current_user(self):  # 改写Base类的这个方法
        # current_user = self.get_secure_cookie('ID')
        current_user = self.session.get('ID')
        if current_user:
            return current_user
        return None

   #  redis加密时,Login继承Base
class LoginHandler(BaseHandler):
    def get(self):
        nextname = self.get_argument('next','')
        self.render('login_1.html',
                    nextname=nextname,
                    error=''
                    )
    def post(self, *args, **kwargs):
        name = self.get_argument('name','')
        password = self.get_argument('password','')
        username = User.by_name(name)
        nextname = self.get_argument('next','')
        print(name, password, nextname)
        if username and username.password==password:
            self.session.set('ID',name)    # session为redis的会话,设置redis的加密cookie
            if nextname:
                self.redirect(nextname)
            else:
                self.redirect('/buy')
        else:
            self.render('login_1.html',
                        nextname=nextname,
                        error='用户名或密码错误'
                        )


class BuyHandler(BaseHandler):
    @authenticated
    def get(self):
        self.write('欢迎您,尊敬的 VIP1000 用户')


application = tornado.web.Application(
    [
        (r"/login", LoginHandler),
        (r"/buy", BuyHandler),
    ],
    template_path='templates',
    login_url='/login',
    cookie_secret='haha',
    pycket={
        'engine': 'redis',   # 连接redis
        'storage': {
            'host': 'localhost',    # 本机
            'port': 6379,       # redis端口
            'db_sessions': 5,   # redis的数据库(0-15个)
            'db_notifications': 11,
            'max_connections': 2 ** 31,
        },
        'cookies': {           # cookie 过期时间
            'expires_days': 30,
            'max_age': 100
        },
    },
    debug=True
)

if __name__ == '__main__':
    tornado.options.parse_command_line()  # 获取命令行的参数 --port=1040 就能使用这个参数
    print(options.port)
    print(options.version)

    http_server = tornado.httpserver.HTTPServer(application)
    application.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

 防止cookie被盗用后,用这个虚假cookie去欺骗服务器(防止跨域攻击)

思路:在返回登录界面时发送一串独有的标记,这个标记和cookie相同,判断是否为服务器发出来登陆页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% if error %}
用户名或密码错误
{% end %}

{% if nextname == '' %}
    <form method="post" action="/login">
        {% module xsrf_form_html() %}   # 返回form表单给浏览器时发送独有的标记,和cookie的信息相同。
用来证明是服务器发送的
<p>用户名:<input type="text", name="name"></p> <p>密码:<input type="password", name="password"></p> <input type="submit"> </form> {% else %} <form method="post" action="/login?next={{nextname}}"> {% module xsrf_form_html() %} <p>用户名:<input type="text", name="name"></p> <p>密码:<input type="password", name="password"></p> <input type="submit"> {% end %} </form> </body> </html>

 

 

posted on 2018-03-15 09:43  .Tang  阅读(1421)  评论(0编辑  收藏  举报