摘要:在保存登錄狀態與注銷功能這篇文章中,我們使用了來保存,實際上默認的功能,是客戶端,與之相對的是服務器端。今天我們來實現服務器端,原理很簡單,實際上在編程實現和這篇文章中我們已經做過了。現在我們用數據庫來保存,并為其設置有效期。
在11.保存登錄狀態與注銷功能這篇文章中,我們使用了session來保存username,實際上Flask默認的session功能,是客戶端session(client-side session),與之相對的是服務器端session(server-side session)。簡單來說,這里的客戶端session是將username加密后,以cookie的形式返還給客戶端,客戶端后續訪問網站就攜帶著這個cookie,服務器解密cookie得到username。也就是說,如果知道了加密方法和cookie內容,就可以解密出username,這樣是不夠安全的。
今天我們來實現服務器端session(server-side session),原理很簡單,實際上在【python socket編程】—— 5.實現cookie和session這篇文章中我們已經做過了。現在我們用數據庫來保存session,并為其設置有效期。整個邏輯是這樣的:用戶登錄后,生成一個隨機字符串,將其作為session id,與對應的username和過期時間一起存入數據庫,然后將session id作為cookie返回給客戶端,客戶端后續訪問時,攜帶著含有session id的cookie,服務器通過cookie中的session id在數據庫中檢索session數據,判斷登錄狀態。
建立一個sessions表(ORM模型)來存儲session,字段如下:
class MySession(db.Model): __tablename__ = "sessions" id = db.Column(db.Integer, primary_key=True, autoincrement=True) # s_id代表session id,也是后面返回給客戶端的cookie s_id = db.Column(db.String(24), nullable=False) username = db.Column(db.String(64), nullable=False) start_time = db.Column(db.DateTime, nullable=False) expire_time = db.Column(db.DateTime, nullable=False)
視圖函數代碼如下:
@app.route("/session/", methods=["GET", "POST"]) def test_session(): username = None if request.method == "GET": s_id = request.cookies.get("sid") if s_id: mysession = MySession.query.filter(MySession.s_id == s_id).first() if mysession and mysession.expire_time > datetime.now(): username = mysession.username return render_template("session.html", username=username) else: username = request.form.get("username") s_id = random_strings(24) now = datetime.now() expire_time = now + timedelta(seconds=10) mysession = MySession(s_id=s_id, username=username, start_time=now, expire_time=expire_time) db.session.add(mysession) db.session.commit() response = make_response(redirect(url_for("test_session"))) response.set_cookie("sid", s_id) return response
我們從POST方法講起,當用戶POST一個username過來時(為了簡單,session.html只有用戶名沒有密碼),生成一個隨機字符串(random_strings是自己編寫的一個小函數)作為session id,然后獲取現在的時間now和過期時間expire_time(為了演示方便,過期時間是10秒之后),然后將這些信息存入MySession模型中,最后使用make_response方法生成一個response對象(這個對象有set_cookie方法,這也是Flask設置cookie的常規方法),并為其設置cookie,set_cookie第一個參數"sid"是key,第二個參數是value(session id),之后返回response對象。當請求是GET時候,首先就會使用request.cookies.get("sid")去獲取cookie中的session id,如果獲取到并且還在過期時間內,則向html傳入username表明當前已經登錄的用戶。
最后html的內容如下:
Title {% if username %}Welcome {{ username }}
{% else %} {% endif %}
效果展示:
未登錄時:
登錄后:
此時數據庫中的session信息:
瀏覽器中的cookie內容:
過期之后瀏覽器仍然攜帶這個cookie,但刷新網頁又變成未登錄的狀態了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/41394.html
摘要:通過配置規則和單位使用或來解決。其他關于我個人的一系列學習介紹及總結有興趣可以參閱自學筆記一安裝使用篇自學筆記二插件篇自學筆記二番外篇一自學筆記二番外篇二 利用PostCSS解決移動端REM適配問題 上一期有提到結合postcss-px2rem插件來處理移動端適配的方案,以及相關的避坑方法,之后總覺得這個解決方案問題太多,也就誕生了另一套方案運用postcss-pxtorem插件來進行...
摘要:之前寫過一系列的文章,也承諾過會盡快有的介紹。所以這次還是給大家分享一個使用解決問題的案例,希望對大家在使用的時候有一點點啟發。上述這一套復雜的業務邏輯如果使用傳統編碼方式將是極其復雜的。 之前寫過一系列RxJava1的文章,也承諾過會盡快有RxJava2的介紹。無奈實際項目中還未真正的使用RxJava2,不敢妄動筆墨。所以這次還是給大家分享一個使用RxJava1解決問題的案例,希望對...
摘要:番外關于搜狐面試結果早上十點半去的,一面之后緊接著又是一面。手寫模擬的雙向數據綁定手寫有哪些屬性總結今天的面試的考察基本上都是,難度一般。今天月份剛剛畢業,經過這次搜狐面試,已經成功拿到搜狐,現在已經成功入職。 番外:關于搜狐面試 結果 早上十點半去的,一面之后緊接著又是一面。感覺還好,應該還能繼續! 問題 一面: 1.數組去重,并計算時間復雜度。找出最優解決方案。(手寫代碼)2.定義...
閱讀 662·2021-11-24 09:39
閱讀 2315·2021-11-22 13:54
閱讀 2197·2021-09-23 11:46
閱讀 3246·2019-08-30 15:55
閱讀 2679·2019-08-30 15:54
閱讀 2403·2019-08-30 14:18
閱讀 1546·2019-08-29 14:15
閱讀 2732·2019-08-29 13:49