在上篇文章中襟己,我們學習了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)文章!