99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Tornado 身份驗(yàn)證和安全性

2022-03-08 10:40 更新

Cookie

您可以使用?set_cookie?方法在用戶瀏覽器中設(shè)置 cookie:

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        if not self.get_cookie("mycookie"):
            self.set_cookie("mycookie", "myvalue")
            self.write("Your cookie was not set yet!")
        else:
            self.write("Your cookie was set!")

Cookie 不安全,很容易被修改。 如果您需要設(shè)置 cookie,例如,識(shí)別當(dāng)前登錄的用戶,您需要簽署您的 cookie 以防止偽造。 Tornado 支持使用 set_secure_cookie 和 get_secure_cookie 方法簽名的 cookie。 要使用這些方法,您需要在創(chuàng)建應(yīng)用程序時(shí)指定一個(gè)名為 ?cookie_secret? 的密鑰。 您可以將應(yīng)用程序設(shè)置作為關(guān)鍵字參數(shù)傳遞給您的應(yīng)用程序:

application = tornado.web.Application([
    (r"/", MainHandler),
], cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__")

除了時(shí)間戳和 HMAC 簽名之外,簽名的 cookie 還包含 cookie 的編碼值。 如果 cookie 是舊的或者簽名不匹配,?get_secure_cookie? 將返回 ?None? ,就好像 cookie 沒(méi)有設(shè)置一樣。 上面示例的安全版本:

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        if not self.get_secure_cookie("mycookie"):
            self.set_secure_cookie("mycookie", "myvalue")
            self.write("Your cookie was not set yet!")
        else:
            self.write("Your cookie was set!")

Tornado 的安全 cookie 保證完整性,但不保證機(jī)密性。 也就是說(shuō),cookie 無(wú)法修改,但用戶可以看到其內(nèi)容。 ?cookie_secret? 是一個(gè)對(duì)稱密鑰,必須保密——任何獲得此密鑰值的人都可以生成自己的簽名 cookie。

默認(rèn)情況下,Tornado 的安全 cookie 會(huì)在 30 天后過(guò)期。 要更改此設(shè)置,請(qǐng)使用 ?set_secure_cookie? 的 ?expires_days? 關(guān)鍵字參數(shù)和 ?get_secure_cookie? 的 ?max_age_days? 參數(shù)。 這兩個(gè)值分別傳遞,以便您可以例如 對(duì)于大多數(shù)用途,cookie 的有效期為 30 天,但對(duì)于某些敏感操作(例如更改帳單信息),您在讀取 cookie 時(shí)使用較小的 ?max_age_days?。

Tornado 還支持多個(gè)簽名密鑰以啟用簽名密鑰輪換。 那么 ?cookie_secret? 必須是一個(gè)字典,其中整數(shù)密鑰版本作為鍵,相應(yīng)的秘密作為值。 然后必須將當(dāng)前使用的簽名密鑰設(shè)置為 ?key_version? 應(yīng)用程序設(shè)置,但如果在 cookie 中設(shè)置了正確的密鑰版本,則允許 dict 中的所有其他密鑰進(jìn)行 cookie 簽名驗(yàn)證。 要實(shí)現(xiàn) cookie 更新,可以通過(guò) get_secure_cookie_key_version 查詢當(dāng)前的簽名密鑰版本。

用戶認(rèn)證

當(dāng)前經(jīng)過(guò)身份驗(yàn)證的用戶在每個(gè)請(qǐng)求處理程序中作為 self.current_user 可用,在每個(gè)模板中作為 ?current_user? 可用。 默認(rèn)情況下,?current_user? 為?None?。

要在您的應(yīng)用程序中實(shí)現(xiàn)用戶身份驗(yàn)證,您需要覆蓋請(qǐng)求處理程序中的 ?get_current_user()方法,以根據(jù)例如 cookie 的值來(lái)確定當(dāng)前用戶。 下面是一個(gè)示例,用戶只需指定昵稱即可登錄應(yīng)用程序,然后將昵稱保存在 cookie 中:

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(BaseHandler):
    def get(self):
        self.write('<html><body><form action="/login" method="post">'
                   'Name: <input type="text" name="name">'
                   '<input type="submit" value="Sign in">'
                   '</form></body></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="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__")

您可以要求用戶使用 Python decorator tornado.web.authenticated 登錄。 如果一個(gè)請(qǐng)求使用這個(gè)裝飾器發(fā)送到一個(gè)方法,并且用戶沒(méi)有登錄,他們將被重定向到 ?login_url?(另一個(gè)應(yīng)用程序設(shè)置)。 上面的例子可以重寫(xiě):

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

settings = {
    "cookie_secret": "__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
    "login_url": "/login",
}
application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/login", LoginHandler),
], **settings)

如果你用?authenticated?裝飾器裝飾 ?post()? 方法,并且用戶沒(méi)有登錄,服務(wù)器將發(fā)送一個(gè) ?403? 響應(yīng)。 ?@authenticated? 裝飾器只是 ?if not self.current_user: self.redirect()? 的簡(jiǎn)寫(xiě),可能不適用于非基于瀏覽器的登錄方案。

第三方認(rèn)證

tornado.auth 模塊為網(wǎng)絡(luò)上許多最流行的站點(diǎn)實(shí)現(xiàn)身份驗(yàn)證和授權(quán)協(xié)議,包括 Google/Gmail、Facebook、Twitter 和 FriendFeed。 該模塊包括通過(guò)這些站點(diǎn)登錄用戶的方法,以及在適用的情況下授權(quán)訪問(wèn)服務(wù)的方法,以便您可以下載用戶的通訊錄或代表他們發(fā)布 Twitter 消息。

這是一個(gè)使用 Google 進(jìn)行身份驗(yàn)證的示例處理程序,將 Google 憑據(jù)保存在 cookie 中以供以后訪問(wèn):

class GoogleOAuth2LoginHandler(tornado.web.RequestHandler,
                               tornado.auth.GoogleOAuth2Mixin):
    async def get(self):
        if self.get_argument('code', False):
            user = await self.get_authenticated_user(
                redirect_uri='http://your.site.com/auth/google',
                code=self.get_argument('code'))
            # Save the user with e.g. set_secure_cookie
        else:
            await self.authorize_redirect(
                redirect_uri='http://your.site.com/auth/google',
                client_id=self.settings['google_oauth']['key'],
                scope=['profile', 'email'],
                response_type='code',
                extra_params={'approval_prompt': 'auto'})

跨站請(qǐng)求偽造保護(hù)

防止 XSRF 的普遍接受的解決方案是使用不可預(yù)測(cè)的值對(duì)每個(gè)用戶進(jìn)行 cookie,并將該值作為附加參數(shù)包含在您網(wǎng)站上的每個(gè)表單提交中。 如果 cookie 和表單提交中的值不匹配,那么請(qǐng)求很可能是偽造的。

Tornado 帶有內(nèi)置的 XSRF 保護(hù)。 要將其包含在您的站點(diǎn)中,請(qǐng)包含應(yīng)用程序設(shè)置 ?xsrf_cookies?:

settings = {
    "cookie_secret": "__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
    "login_url": "/login",
    "xsrf_cookies": True,
}
application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/login", LoginHandler),
], **settings)

如果設(shè)置了 ?xsrf_cookies?,Tornado Web 應(yīng)用程序?qū)樗杏脩粼O(shè)置 ?_xsrf? cookie,并拒絕所有不包含正確 ?_xsrf? 值的 ?POST?、?PUT? 和 ?DELETE? 請(qǐng)求。 如果打開(kāi)此設(shè)置,則需要檢測(cè)通過(guò) ?POST 提交的所有表單以包含此字段。 您可以使用所有模板中可用的特殊 UIModule ?xsrf_form_html()? 來(lái)完成此操作:

<form action="/new_message" method="post">
  {% module xsrf_form_html() %}
  <input type="text" name="message"/>
  <input type="submit" value="Post"/>
</form>

如果您提交 AJAX ?POST? 請(qǐng)求,您還需要檢測(cè) JavaScript 以在每個(gè)請(qǐng)求中包含 ?_xsrf? 值。 這是我們?cè)?nbsp;FriendFeed 中用于 AJAX ?POST? 請(qǐng)求的 jQuery 函數(shù),它會(huì)自動(dòng)將 ?_xsrf? 值添加到所有請(qǐng)求中:

function getCookie(name) {
    var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
    return r ? r[1] : undefined;
}

jQuery.postJSON = function(url, args, callback) {
    args._xsrf = getCookie("_xsrf");
    $.ajax({url: url, data: $.param(args), dataType: "text", type: "POST",
        success: function(response) {
        callback(eval("(" + response + ")"));
    }});
};

對(duì)于 ?PUT ?和 ?DELETE ?請(qǐng)求(以及不使用表單編碼參數(shù)的 ?POST ?請(qǐng)求),XSRF 令牌也可以通過(guò)名為 ?X-XSRFToken? 的 HTTP 標(biāo)頭傳遞。 XSRF cookie 通常在使用 ?xsrf_form_html? 時(shí)設(shè)置,但在不使用任何常規(guī)表單的純 JavaScript 應(yīng)用程序中,您可能需要手動(dòng)訪問(wèn) ?self.xsrf_token?(只需讀取屬性就足以將 cookie 設(shè)置為副作用) .

如果您需要基于每個(gè)處理程序自定義 XSRF 行為,您可以覆蓋 RequestHandler.check_xsrf_cookie()。 例如,如果您的 API 的身份驗(yàn)證不使用 cookie,您可能希望通過(guò)使 ?check_xsrf_cookie()? 什么都不做來(lái)禁用 XSRF 保護(hù)。 但是,如果您同時(shí)支持 cookie 和非基于 cookie 的身份驗(yàn)證,那么無(wú)論何時(shí)使用 cookie 對(duì)當(dāng)前請(qǐng)求進(jìn)行身份驗(yàn)證,都必須使用 XSRF 保護(hù)。

DNS重新綁定

DNS 重新綁定是一種可以繞過(guò)同源策略并允許外部站點(diǎn)訪問(wèn)專用網(wǎng)絡(luò)上的資源的攻擊。 這種攻擊涉及一個(gè) DNS 名稱(具有短 TTL),該名稱在返回由攻擊者控制的 IP 地址和由受害者控制的 IP 地址(通常是可猜測(cè)的私有 IP 地址,例如 ?127.0.0.1? 或 ?192.168.1.1?)之間交替。

使用 TLS 的應(yīng)用程序不容易受到這種攻擊(因?yàn)闉g覽器會(huì)顯示阻止自動(dòng)訪問(wèn)目標(biāo)站點(diǎn)的證書(shū)不匹配警告)。

不能使用 TLS 并依賴網(wǎng)絡(luò)級(jí)訪問(wèn)控制的應(yīng)用程序(例如,假設(shè) ?127.0.0.1? 上的服務(wù)器只能由本地計(jì)算機(jī)訪問(wèn))應(yīng)通過(guò)驗(yàn)證 ?Host? HTTP 表頭來(lái)防止 DNS 重新綁定。 這意味著將限制性主機(jī)名模式傳遞給 HostMatches 路由器或 Application.add_handlers 的第一個(gè)參數(shù):

# BAD: uses a default host pattern of r'.*'
app = Application([('/foo', FooHandler)])

# GOOD: only matches localhost or its ip address.
app = Application()
app.add_handlers(r'(localhost|127\.0\.0\.1)',
                 [('/foo', FooHandler)])

# GOOD: same as previous example using tornado.routing.
app = Application([
    (HostMatches(r'(localhost|127\.0\.0\.1)'),
        [('/foo', FooHandler)]),
    ])

此外,Application 和 DefaultHostMatches 路由器的?default_host?參數(shù)不得用于可能易受 DNS 重新綁定攻擊的應(yīng)用程序中,因?yàn)樗c通配符主機(jī)模式具有類似的效果。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)