Flask框架——Session與Cookie

在上篇文章中襟己,我們學習了Flask框架——模型關(guān)系(多對多關(guān)系),這篇文章我們學習Flask框架——Cookie與Session。

在瀏覽網(wǎng)站的過程中,我們經(jīng)常會遇到需要登錄的情況翘紊,有些頁面只有登錄之后才可以訪問,登錄之后關(guān)閉瀏覽器藐唠,再重新打開該網(wǎng)站時帆疟,就自動登錄了,但有時候過段時間又需要重新登錄宇立,這里面涉及了Cookie和Session的相關(guān)知識踪宠。

無狀態(tài)HTTP

在了解Cookie和Session之前,我們先了解HTTP的一個特點——無狀態(tài)妈嘹。

HTTP的無狀態(tài)是指HTTP協(xié)議對事務處理是沒有記憶能力的柳琢,服務器并不知道客戶端處于什么狀態(tài)∪罅常客戶端向服務器發(fā)送請求后柬脸,服務器解析請求并返回響應,服務器負責完成這個過程毙驯,但服務器不會記錄前后狀態(tài)的變化倒堕,也就是缺少狀態(tài)的記錄。

假如這個請求是需要用戶登錄后才能發(fā)送的爆价,由于服務器沒有記錄我們登錄的狀態(tài)垦巴,那么客戶端就必須登錄后再重新發(fā)送請求,就導致需要傳遞一些重復的請求才能獲取相應的響應允坚,這樣太浪費資源了魂那,于是可以識別用戶信息的技術(shù)出現(xiàn)了——Cookie和Session。

  • Cookie:客戶端稠项,有了Cookie涯雅,瀏覽器在下次訪問相同網(wǎng)頁時,就會自動附帶上它展运,并發(fā)送給服務器活逆,服務器通過Cookie識別出是哪個用戶在訪問精刷,然后判斷此用戶是否處于登錄狀態(tài),并返回對應的響應蔗候。

  • Session:服務端怒允,用來保存用戶的Session信息、屬性以及配置信息锈遥。

好了纫事,簡單了解了無狀態(tài)HTTP、Cookie及Session的概念后所灸,接下來我們使用Flask框架來實現(xiàn)網(wǎng)站狀態(tài)的保持丽惶。

Cookie

Cookie用來識別用戶身份,在Flask程序中爬立,如何利用Cookie保持用戶狀態(tài)呢钾唬。在客戶端第一次請求服務器時,服務器會返回一個響應頭帶有Set-Cookie字段的響應給客戶端侠驯,這個字段用來標記用戶抡秆。客戶端瀏覽器會把Cookie保存起來吟策,當下一次請求相同的網(wǎng)站時儒士,把保存的Cookie放在一起交給服務器,服務器通過Cookie來識別用戶檩坚,并返回相應的響應乍桂。

在Flask中,Cookie是在響應對象中設置的效床,所以先要在視圖函數(shù)的返回值中獲取響應對象睹酌,再使用set-cookie函數(shù)存儲Cookie。

創(chuàng)建一個Flask項目剩檀,其app.py代碼如下所示:

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

#登錄視圖函數(shù)
@app.route('/login')
def login():
    return render_template('login.html')    #渲染login.html文件

if __name__ == '__main__':
    app.run()

這里創(chuàng)建一個簡單的登錄視圖函數(shù)憋沿,在templates文件夾中創(chuàng)建模板文件login.html,通過render_template()方法渲染login.html沪猴,login.html代碼如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
</head>
<body>
      <form action = "/getcookie" method = "POST">
         <p><h3>請輸入你的用戶名:</h3></p>
         <p><input type = 'text' name = 'username'/></p>
         <p><input type = 'submit' value = 'Login'/></p>
      </form>
</body>
</html>

這個模板文件login很簡單辐啄,通過form表單接收用戶輸入的用戶名,當點擊Login按鈕時运嗜,將用戶名傳遞到getcookie視圖函數(shù)中壶辜,在app.py文件中g(shù)etcookie視圖函數(shù)代碼如下所示:

@app.route('/getcookie',methods=['POST','GET'])
def getcookie():
    if request.method=='POST':          #請求類型為POST
        username=request.form['username']   #獲取請求中的username
        response = redirect(url_for('index'))   #重定向到index路由中,并返回響應對象
        response.set_cookie('username',str(username),max_age=18000) #設置cookie值及屬性
        return response

當請求類型為POST時担租,通過request.form()方法將請求中的username獲取并保存在username中砸民,使用redirect重定向到index視圖函數(shù)中,redirect()方法的返回值是個響應對象,獲得響應對象后岭参,我們通過.set_cookie()方法來設置cookie反惕。

.set_cookie()方法語法結(jié)構(gòu)如下:

Response.set_cookie(
    key,        #鍵
    value='',    #值
    max_age=None,   #cookie壽命,以秒為單位演侯,None表示http-only
    expires=None,   #失效時間姿染,datetime對象或者時間戳
    path='/',       #cookie的有效路徑
    domain=None,    #cookie有效域
    secure=None,
    httponly=False)

除了通過redirect()方法獲得響應對象外,還可以通過以下方式獲让爰省:

response=render_template()      #模板渲染       
response=Response()             #Response對象
response=make_response()        #自定義response對象
response=jsonify()              #返回包含json格式數(shù)據(jù)響應

通過getcookie視圖函數(shù)設置cookie值后悬赏,重定向到index視圖函數(shù)中,在app.py文件中index代碼如下所示:

@app.route('/index')
def index():
    username = request.cookies.get('username',None)     #獲取cookie值
    if username!=None:
        return render_template('logout.html',username=username) #渲染logout.html到網(wǎng)頁中并傳遞username值
    else:
        return render_template('logout.html')

在index視圖函數(shù)中娄徊,通過request.cookies.get()方法獲取名為username的cookie值舷嗡,根據(jù)username值決定是否將username值傳遞到渲染的logout.html網(wǎng)頁中。

在templates文件夾中創(chuàng)建模板文件logout.html嵌莉,logout.html文件很簡單,代碼如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>現(xiàn)在登錄的用戶為{{ username }}</h3>
<a href="{{ url_for('logout') }}">退出</a>
</body>
</html>

logout.html接收到username值后就會將該值呈現(xiàn)在網(wǎng)頁中捻脖,接下來我們打開http://127.0.0.1:5000/login并在文本框中輸入zhangsan锐峭,如下圖所示:


點擊登錄直接跳轉(zhuǎn)到http://127.0.0.1:5000/index,如下圖所示:
打開瀏覽器設置查看Cookie的存儲可婶,

在瀏覽器設置中沿癞,我們可以找到Cookie的存儲情況,在cookie的有效時間內(nèi)矛渴,每次訪問http://127.0.0.1:5000/index自動登錄椎扬。

可以通過set_cookie()方法設置cookie,也可以通過.delete_cookie()方法刪除cookie具温,這里我們通過創(chuàng)建logout視圖函數(shù)來實現(xiàn)對cookie的刪除蚕涤,在app.py文件中l(wèi)ogout視圖函數(shù)代碼如下所示:

@app.route('/logout')
def logout():
    response = redirect(url_for('index'))   #重定向到index視圖函數(shù)中,獲取響應對象
    response.delete_cookie('username')      #刪除名為username的cookie值
    return response

獲取到響應對象再通過delete_cookie()方法將cookie值刪除铣猩。當我們打開http://127.0.0.1:5000/index網(wǎng)頁時揖铜,點擊退出,如下圖所示:


這時我們在瀏覽器設置中查找cookie值达皿,就會發(fā)現(xiàn)剛才上圖的cookie信息已經(jīng)被刪除天吓,所以我們重新打開http://127.0.0.1:5000/index時,沒有用戶信息峦椰。

學習通過Cookie來保持網(wǎng)頁的狀態(tài)后龄寞,接下來我們通過Session來保持網(wǎng)頁的狀態(tài)。

Session

Session汤功,也稱為會話物邑,本義是指有起有終的一系列動作、消息。

在Web中拂封,Session對象用來存儲特定用戶Session所需的屬性及配置信息茬射。這樣當用戶在頁面之間跳轉(zhuǎn)時,存儲在Session對象中變量將不會丟失冒签,會在整個用戶中一直存在下去在抛。當用戶請求來自程序頁面時,該用戶還沒有Session的話萧恕,那么Web服務器將自動創(chuàng)建一個Session對象刚梭,那么當Session過期或被放棄后,服務器將終止該Session票唆。

在Flask框架中朴读,session是當做字典來使用的,接下來我們通過代碼來使用session實現(xiàn)網(wǎng)頁狀態(tài)的保持走趋。

創(chuàng)建Flask項目衅金,其app.py文件代碼如下所示:

from flask import Flask, render_template, request, redirect, url_for, session
app = Flask(__name__)
app.config['SECRET_KEY']='SDFAFASD'         #配置SECRET_KEY
# 登錄視圖函數(shù)
@app.route('/login')
def login():
    return render_template('login.html')    #渲染login.html模板
if __name__ == '__main__':
    app.run()

因為Flask的session是通過加密之后放到了cookie中,所以只要用到了Flask的session模塊就一定要配置“SECRET_KEY”這個全局宏簿煌。該值可以是任意字符串氮唯。

我們創(chuàng)建一個簡單的登錄視圖函數(shù),通過render_template()方法將login.html模板文件渲染在網(wǎng)頁中姨伟,這里的login.html我們用上面Cookie的login.html惩琉。

接下來我們創(chuàng)建設置Session的getsession視圖函數(shù),代碼如下所示:

@app.route('/getsession',methods=['POST','GET'])
def getsession():
    if request.method=='POST':
        username=request.form['username']       #獲取請求的username值
        session['username']=username            #設置session為username
        session.permanent = True               #設置session有效時長
        return redirect(url_for('index'))       #將網(wǎng)頁重定向到index中

獲取到請求username值夺荒,由于session是以字典的形式存在瞒渠,所以我們需要以session['...‘]=值的形式傳遞,這個我們通過session.permanent=True技扼,將session的有效期延長至一個月伍玖,當沒有設置session的有效期時,當關(guān)閉瀏覽器時剿吻,網(wǎng)頁就是刪除session數(shù)據(jù)信息私沮。除了將session有效期設置為一個月,還可以通過配置PERMANENT_SESSION_LIFETIME指定session有效時間和橙,代碼如下所示:

app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=2)   #有效時長為2小時

通過getsession視圖函數(shù)設置session值后仔燕,重定向到index視圖函數(shù)中,在app.py文件中index代碼如下所示:

@app.route('/index')
def index():
    username=session.get('username')            #獲取session中的username值
    if username!=None:
        return render_template('logout.html',username=username)     #渲染logou.html并傳遞username值
    else:
        return render_template('logout.html')

和Cookie的index視圖函數(shù)類似魔招,只是將request.cookie改為session晰搀,在獲取到username之后,根據(jù)username值判斷是否傳入render_template()渲染的網(wǎng)頁中办斑。這里的logout.html模板是用上面Cookie創(chuàng)建的logout.html模板外恕。

打開http://127.0.0.1:5000/login并在文本框中輸入zhangsan杆逗,如下圖所示:


點擊登錄直接跳轉(zhuǎn)到http://127.0.0.1:5000/index,如下圖所示:

在session的有效時間內(nèi)鳞疲,每次訪問http://127.0.0.1:5000/index自動登錄罪郊。

如何刪除session數(shù)據(jù)信息呢?刪除session數(shù)據(jù)很簡單尚洽,代碼如下所示:

@app.route('/logout')
def logout():
    session.pop('username')                 #刪除session中的username值
    session.clear()                        #刪除session的所有值
    return redirect(url_for('index'))       #重定向到index頁面中

當我們打開http://127.0.0.1:5000/index網(wǎng)頁時悔橄,點擊退出,如下圖所示:


好了腺毫,關(guān)于Flask框架——Session和Cookie就講到這里了癣疟,感謝觀看!3本啤睛挚!下篇文章學習Flask框架——flask-caching緩存。

公眾號:白巧克力LIN

該公眾號發(fā)布Python急黎、數(shù)據(jù)庫扎狱、Linux、Flask勃教、自動化測試淤击、Git等相關(guān)文章!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荣回,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子戈咳,更是在濱河造成了極大的恐慌心软,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件著蛙,死亡現(xiàn)場離奇詭異删铃,居然都是意外死亡,警方通過查閱死者的電腦和手機踏堡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門猎唁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人顷蟆,你說我怎么就攤上這事诫隅。” “怎么了帐偎?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵逐纬,是天一觀的道長。 經(jīng)常有香客問我削樊,道長豁生,這世上最難降的妖魔是什么兔毒? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮甸箱,結(jié)果婚禮上育叁,老公的妹妹穿的比我還像新娘。我一直安慰自己芍殖,他們只是感情好豪嗽,可當我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著围小,像睡著了一般昵骤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肯适,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天变秦,我揣著相機與錄音,去河邊找鬼框舔。 笑死蹦玫,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的刘绣。 我是一名探鬼主播樱溉,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纬凤!你這毒婦竟也來了福贞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤停士,失蹤者是張志新(化名)和其女友劉穎挖帘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恋技,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡拇舀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜻底。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骄崩。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖薄辅,靈堂內(nèi)的尸體忽然破棺而出要拂,到底是詐尸還是另有隱情,我是刑警寧澤站楚,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布宇弛,位于F島的核電站,受9級特大地震影響源请,放射性物質(zhì)發(fā)生泄漏枪芒。R本人自食惡果不足惜彻况,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望舅踪。 院中可真熱鬧纽甘,春花似錦、人聲如沸抽碌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽货徙。三九已至左权,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痴颊,已是汗流浹背赏迟。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蠢棱,地道東北人锌杀。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像泻仙,于是被迫代替她去往敵國和親糕再。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,747評論 2 361

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

  • ? ??在第1章玉转,我們已經(jīng)了解了Flask的基本知識突想,如果想要進一步開發(fā)更復雜的Flask應用,我們就得了解F...
    懵懂_傻孩紙閱讀 2,966評論 0 4
  • 前言 本文為《Flask Web開發(fā):基于Python的Web應用開發(fā)實戰(zhàn)》第2版 的內(nèi)容摘要 摘要 第 1 章:...
    Whyn閱讀 1,146評論 0 0
  • 第二部分 Blog例子 第八章 用戶驗證 大部分程序需要追蹤用戶身份究抓。當用戶連接到程序猾担,通過一系列步驟使自己的身份...
    易木成華閱讀 1,295評論 0 4
  • URL和視圖 安裝Homebrew 在終端輸入以下代碼,安裝Homebrew: Python安裝 mac環(huán)境下默認...
    云中的Jason閱讀 1,289評論 0 4
  • Table of Contents WSGIwsgi服務器作用wsgirefhttp協(xié)議無狀態(tài)漩蟆,短連接垒探,長連接co...
    四月天_da7e閱讀 453評論 0 0