flask 中幾種在所有請求之前進行驗證的方法之間的差別

在所有請求之前添加鉤子

在做驗證是否是登陸用戶之類的功能時买窟,一定會涉及到與此相關(guān)的知識點挽鞠。

對于直接用 app.add_url_rule() 或者使用 @app.route(...) 的方式來定義路由的情況院峡,我們可以使用@app.before_request() 裝飾器來實現(xiàn)在所有請求之前執(zhí)行某一些驗證邏輯代碼咱士。

但是對于用blueprint來定義各種路由的方式影斑,blueprint.before_request 不再是一個裝飾器框仔,而是一個函數(shù)惠遏,并且接受一個參數(shù)砾跃,參數(shù)是一個方法名 func。也就是在執(zhí)行所有請求之前會先執(zhí)行這個 func 方法

最基本的代碼是:

def blueprint_validate_session_in_stock():
    print 'this is [before_request] in blueprint'

def create_app(config_name):
    app=Flask(__name__)
    app.config.from_object(config.config['base'])

    stocks_blueprint.before_request(
        blueprint_validate_session_in_stock)

    app.register_blueprint(main_blueprint)
    app.register_blueprint(stocks_blueprint)

    return app

這樣的話节吮,每次訪問 stocks_blueprint 模塊中的頁面抽高,都會打印:this is [before_request] in blueprint

一個有益的對比

由于 blueprint 不僅有 before_request() 方法透绩,還有 before_app_request() 方法翘骂,還有 before_app_first_request() 方法,再加上在 app 層面還有 app.before_request() 方法帚豪。這四種方法究竟在哪些情況下執(zhí)行碳竟?誰先誰后?這些問題都將直接影響到網(wǎng)站訪問控制的邏輯狸臣,如果理解錯誤莹桅,還可能造成一些訪問的死循環(huán)。

我們將前面的代碼改為:

#encoding:utf8

from flask import Flask,redirect
import config

from controllers import main_blueprint
from controllers.stocks import stocks_blueprint


def validate_session():
    print 'over the top! this is before_request\n'
def blueprint_validate_app_session_in_stock():
    print '\tthis is [before_app_request] in blueprint\n'
def blueprint_validate_app_session_first_in_stock():
    print '\tthis is [before_app_first_request] in blueprint\n'
def blueprint_validate_session_in_stock():
    print '\tthis is [before_request] in blueprint\n'
    session=None
    if session==None:
        return redirect('/login')

def create_app(config_name):
    app=Flask(__name__)
    app.config.from_object(config.config['base'])

    app.before_request(validate_session)
    stocks_blueprint.before_request(
        blueprint_validate_session_in_stock)
    stocks_blueprint.before_app_first_request(
        blueprint_validate_app_session_first_in_stock
    )
    stocks_blueprint.before_app_request(
        blueprint_validate_app_session_in_stock)

    app.register_blueprint(main_blueprint)
    app.register_blueprint(stocks_blueprint)

    # print app.url_map
    return app

代碼的意圖是:訪問 blueprint_stock 的根頁面時烛亦,要做 session 驗證统翩,如果沒有 session 就跳轉(zhuǎn)到 login 頁面去

我們首先訪問網(wǎng)站根頁面,然后點擊跳轉(zhuǎn)到 stock 頁面此洲,所看到的打印記錄是:

# 這是訪問網(wǎng)站根頁面的反饋

    this is [before_app_first_request] in blueprint

over the top! this is before_request

        this is [before_app_request] in blueprint

127.0.0.1 - - [25/Sep/2017 11:45:59] "GET / HTTP/1.1" 200 -

# 這是訪問 stock 根頁面的反饋

over the top! this is before_request

        this is [before_app_request] in blueprint

        this is [before_request] in blueprint

127.0.0.1 - - [25/Sep/2017 11:46:01] "GET /stocks/ HTTP/1.1" 302 -

# 這是跳轉(zhuǎn)到 login 頁面的反饋

over the top! this is before_request

        this is [before_app_request] in blueprint

127.0.0.1 - - [25/Sep/2017 11:46:01] "GET /login HTTP/1.1" 200 -

從上面的打印結(jié)果來對比厂汗,可以得出如下結(jié)論:

  • blueprint.before_app_request 會影響全局,即訪問網(wǎng)站根頁面或其他頁面時呜师,它都會生效

  • blueprint.before_app_request 會最先執(zhí)行娶桦,先于 app.before_request

  • blueprint.before_app_first_request 會影響全局,但是只執(zhí)行一次汁汗,適合用在初始化某些變量衷畦,它的執(zhí)行順序是在 app.before_request 之后

  • blueprint.before_app_request 要慎用,假如上面的代碼中將驗證 session 不存在就跳轉(zhuǎn)到 login 頁面的邏輯代碼知牌,寫在了 blueprint_validate_app_session_in_stock() 中祈争,就會造成訪問的死循環(huán)! 因為訪問 login 頁面時角寸,這個驗證的邏輯代碼同樣會生效:發(fā)現(xiàn)沒有 session菩混,又一次跳轉(zhuǎn)到 login 頁面忿墅,造成頁面一直在刷新!

關(guān)于頁面刷新

如果用戶停留在某一頁面沮峡,只是在瀏覽器上點擊了刷新疚脐,會有什么效果呢?我們將上面的代碼中驗證 session 不存在就跳轉(zhuǎn)的 login 頁面的代碼去掉后邢疙,即注釋掉這部分代碼:

#session=None
#    if session==None:
#        return redirect('/login')

直接訪問 blueprint_stock 的根頁面來查看一下打印結(jié)果:

# 這是第一次訪問的打印結(jié)果

        this is [before_app_first_request] in blueprint

over the top! this is before_request

        this is [before_app_request] in blueprint

        this is [before_request] in blueprint

127.0.0.1 - - [25/Sep/2017 11:56:25] "GET /stocks/ HTTP/1.1" 200 -

# 這是用戶點擊刷新后的打印結(jié)果:

over the top! this is before_request

        this is [before_app_request] in blueprint

        this is [before_request] in blueprint

127.0.0.1 - - [25/Sep/2017 11:56:48] "GET /stocks/ HTTP/1.1" 200 -

可以看到棍弄,刷新后有兩個變化:

  • 執(zhí)行順序變了,刷新后首先執(zhí)行的是 app.before_request
  • 刷新后 blueprint.before_app_first_request 不執(zhí)行了疟游,這個很好理解

結(jié)論

  • 一定要慎用 blueprint.before_app_request
  • blueprint 層面沒有 before_first_request呼畸,如果要使用 blueprint.before_app_first_request 等同于 app.before_first_request 了,這個也要慎用颁虐。
  • 對于 blueprint.before_app_first_request 的應用場景是在各個 blueprint 中可以單獨添加一些自己需要初始化的變量蛮原,各個 blueprint 中的這個操作相互是不會覆蓋的,只是在 app 層面的 before_first_request 中做“加操作”聪廉,避免了直接修改 app.before_first_request 全局型代碼在開發(fā)管理層面上帶來的不便(假如app層面的代碼和各個 blueprint 由不同的人維護)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市故慈,隨后出現(xiàn)的幾起案子板熊,更是在濱河造成了極大的恐慌,老刑警劉巖察绷,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件干签,死亡現(xiàn)場離奇詭異,居然都是意外死亡拆撼,警方通過查閱死者的電腦和手機容劳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闸度,“玉大人竭贩,你說我怎么就攤上這事≥航” “怎么了留量?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長哟冬。 經(jīng)常有香客問我楼熄,道長,這世上最難降的妖魔是什么浩峡? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任可岂,我火速辦了婚禮,結(jié)果婚禮上翰灾,老公的妹妹穿的比我還像新娘缕粹。我一直安慰自己稚茅,他們只是感情好,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布致开。 她就那樣靜靜地躺著峰锁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪双戳。 梳的紋絲不亂的頭發(fā)上虹蒋,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音飒货,去河邊找鬼魄衅。 笑死,一個胖子當著我的面吹牛塘辅,可吹牛的內(nèi)容都是我干的晃虫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼扣墩,長吁一口氣:“原來是場噩夢啊……” “哼哲银!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起呻惕,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤荆责,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后亚脆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體做院,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年濒持,在試婚紗的時候發(fā)現(xiàn)自己被綠了键耕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡柑营,死狀恐怖屈雄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情官套,我是刑警寧澤棚亩,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站虏杰,受9級特大地震影響讥蟆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纺阔,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一瘸彤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧笛钝,春花似錦质况、人聲如沸愕宋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽中贝。三九已至,卻和暖如春臼朗,著一層夾襖步出監(jiān)牢的瞬間邻寿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工视哑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绣否,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓挡毅,卻偏偏與公主長得像蒜撮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子跪呈,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容

  • 22年12月更新:個人網(wǎng)站關(guān)停段磨,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,189評論 22 257
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)耗绿,斷路器苹支,智...
    卡卡羅2017閱讀 134,711評論 18 139
  • [TOC]一直想做源碼閱讀這件事,總感覺難度太高時間太少缭乘,可望不可見沐序。最近正好時間充裕琉用,決定試試做一下堕绩,并記錄一下...
    何柯君閱讀 7,193評論 3 98
  • 最近在學習flask,用到flask-login邑时,發(fā)現(xiàn)網(wǎng)上只有0.1版本的中文文檔奴紧,看了官方已經(jīng)0.4了,并且添加...
    ZZES_ZCDC閱讀 5,956評論 3 24
  • 計劃是按照每天20頁的速度閱讀晶丘,只是因為這本書太精彩黍氮,讀之欲罷不能,今天提前全部讀完了浅浮,分享幾個印象深刻的概念和觀...
    田心遠閱讀 223評論 1 1