tornado Cookie和auth认证

tornado Cookie和auth认证

使用cookie

  • 关键函数

    1. set_secure_cookie 设置cookie
    2. get_secure_cookie 取得浏览器的cookie
    3. cookie_secret,为了使用以上方法,必须在构造函数中指定该方法
  • 例子,统计浏览器中页面被加载次数的功能

#coding=utf-8
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.options


from tornado.options import define, options
define("port", default=8008, help="run on the given port", type=int)


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        cookie = self.get_secure_cookie("count")
        count = int(cookie) + 1 if cookie else 1
        countString = "1 time" if count == 1 else "%d times" % count
        self.set_secure_cookie("count", str(count))

        self.write(
            '<html><head><title>Cookie Counter</title></head>'
            '<body><h1>You’ve viewed this page %s times.</h1>' % countString +
            '</body></html>'
        )


if __name__ == "__main__":
    tornado.options.parse_command_line()
    settings = {
        "cookie_secret": "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E="
    }
    application = tornado.web.Application([
        (r'/', MainHandler)
    ], **settings)
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()
  • 如果你检查浏览器中的cookie值,会发现count储存的值类似于MQ==|1310335926|8ef174ecc489ea963c5cdc26ab6d41b49502f2e2。Tornado将cookie值编码为Base-64字符串,并添加了一个时间戳和一个cookie内容的HMAC签名。如果cookie的时间戳太旧(或来自未来),或签名和期望值不匹配,get_secure_cookie()函数会认为cookie已经被篡改,并返回None,就好像cookie从没设置过一样
  • self.set_cookie(‘foo’, ‘bar’, httponly=True, secure=True),
    1. secure属性来指示浏览器只通过SSL连接传递cookie
    2. httponly 浏览器对于JavaScript不可访问cookie,这可以防范来自读取cookie值的跨站脚本攻击

xsrf

  • xsrf服务端设置
    settings = {
        "cookie_secret": "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=",
        "xsrf_cookies": True
    }
    application = tornado.web.Application([
        (r'/', MainHandler),
        (r'/purchase', PurchaseHandler),
    ], **settings)
  • html设置. 这个应用标识被设置时,Tornado将拒绝请求参数中不包含正确的_xsrf值的POST、PUT和DELETE请求,post客户端html需要指定xsrf
    <form action="/purchase" method="POST">
        {% raw xsrf_form_html() %}
        <input type="text" name="title" />
        <input type="text" name="quantity" />
        <input type="submit" value="Check Out" />
    </form>
  • xsrf的ajax请求
        function getCookie(name) {
        var c = document.cookie.match("\\b" + name + "=([^;]*)\\b");
        return c ? c[1] : undefined;
    }

    jQuery.postJSON = function(url, data, callback) {
        data._xsrf = getCookie("_xsrf");
        jQuery.ajax({
            url: url,
            data: jQuery.param(data),
            dataType: "json",
            type: "POST",
            success: callback
        });
    }

用户验证

  • 例子
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.options
import os.path

from tornado.options import define, options
define("port", default=7999, help="run on the given port", type=int)


class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        return self.get_secure_cookie("username")


class LoginHandler(BaseHandler):
    def get(self):
        self.render('login_auth.html')

    def post(self):
        self.set_secure_cookie("username", self.get_argument("username"))
        self.redirect("/")


class WelcomeHandler(BaseHandler):

    @tornado.web.authenticated
    def get(self):
        self.render('index_auth.html', user=self.current_user)


class LogoutHandler(BaseHandler):

    def post(self):
        if (self.get_argument("logout", None)):
            self.clear_cookie("username")
            self.redirect("/")


if __name__ == "__main__":
    tornado.options.parse_command_line()

    settings = {
        "template_path": os.path.join(os.path.dirname(__file__), "templates"),
        "cookie_secret": "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=",
        "xsrf_cookies": True,
        "login_url": "/login"
    }

    application = tornado.web.Application([
        (r'/', WelcomeHandler),
        (r'/login', LoginHandler),
        (r'/logout', LogoutHandler)
    ], **settings)

    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()
  • index_auth.html
<html>
    <head>
        <title>Welcome Back!</title>
    </head>
    <body>
        <h1>Welcome back, {{ user }}</h1>
    </body>
</html>
  • login_auth.html
<html>
    <head>
        <title>Please Log In</title>
    </head>

    <body>
        <form action="/login" method="POST">
            {% raw xsrf_form_html() %}
            Username: <input type="text" name="username" />
            <input type="submit" value="Log In" />
        </form>
    </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值