摘要:初步的猜想是第一次和第二次請求間隔太短,數(shù)據(jù)還沒有存進(jìn),到時讀取失敗,帶著這樣的疑問,閱讀了的源碼。源碼非常簡單,沒有復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和算法,讀起來沒費什么勁。當(dāng)過期后,用戶獲取的就為空,就會為用戶重新初始化生成。
歡迎大家訪問我的博客,查看更多內(nèi)容。 背景
最近在做djnago開發(fā)時,遇到一個session問題,過程如下,第一個POST請求時,把數(shù)據(jù)存放在session,在第二次POST時,從session中讀取數(shù)據(jù),完成用戶注冊。在實際的環(huán)境中,發(fā)現(xiàn)有時第二次獲取到的數(shù)據(jù)為空。初步的猜想是第一次和第二次請求間隔太短,數(shù)據(jù)還沒有存進(jìn)mysql,到時讀取失敗,帶著這樣的疑問,閱讀了django session的源碼。 django session源碼非常簡單,沒有復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和算法,讀起來沒費什么勁。session總體結(jié)構(gòu)
session目錄結(jié)構(gòu)如下圖
backends這個目錄中定義了session的數(shù)據(jù)結(jié)構(gòu)和幾種存儲模式
base.py這個定義了session的類dict的數(shù)據(jù)結(jié)構(gòu)
cache.py定義了session的緩存存儲,緩存從django.core.cache中獲取
cached_db.py定義了session的緩存+數(shù)據(jù)庫存儲方式
db.py定義了session的數(shù)據(jù)庫存儲方式
file.py定義了session的文件存儲
signed_cookies.py定義了用于簽名的session存儲方式
middleware.py實現(xiàn)了session中間件的處理過程
models.py定義了session數(shù)據(jù)庫結(jié)構(gòu)
management中是一個工具腳本,作用是清理session
session處理流程 中間件流程
處理請求前
從配置文件SESSION_ENGINE中導(dǎo)入session存儲方式
從用戶cookie中讀取session_key
把session存儲方式賦值給request.session
返回請求前
讀取是否修改session的標(biāo)志
讀取session的過期時間
判斷如果session被標(biāo)志位修改或者配置文件中指定了SESSION_SAVE_EVERY_REQUEST,在狀態(tài)碼不為500時,存儲session,設(shè)置用戶cookie
session數(shù)據(jù)庫結(jié)構(gòu)models.py定義了基于django.db.models session的數(shù)據(jù)庫表結(jié)構(gòu),以及存儲的方法,如果session的value為空的話,則刪除該session,否則把session插入到數(shù)據(jù)庫。
session的表名為django_session,三個字段分別是sessin的key,value以及過期時間
session初始化,根據(jù)session key獲取session內(nèi)容
從cookie中讀取session_key,初始化session,并賦值給request.session
根據(jù)cookie中的內(nèi)容初始化session_key,session的兩個標(biāo)志位access和modify為false
初始化session為python dcit,如果已經(jīng)初始化了,則直接返回該session,如果session_key為None,或者設(shè)置no_load標(biāo)志為True,則直接返回個空dict,如果session_key不為None并且設(shè)置no_load標(biāo)志為False,則load數(shù)據(jù)
如果本地數(shù)據(jù)庫已經(jīng)存在該session,則導(dǎo)入到內(nèi)存,如果不存在,則創(chuàng)建session
- 第一步,生成sessin_key,生成算法如下: def _get_new_session_key(self): while True: session_key = get_random_string(32, VALID_KEY_CHARS) if not self.exists(session_key): break return session_key``` 這邊有個問題,但用戶量上百萬時,這個生成算法隨機(jī)重復(fù)的概率還是挺高的,所以這地方可以根據(jù)自己的需求做適當(dāng)?shù)膬?yōu)化 - 第二步:保存session到數(shù)據(jù)庫 - 第三步:初始化session為空
session的操作
session為類dict結(jié)構(gòu),可以像操作dict一樣操作session
session的存儲,修改session內(nèi)容
在返回用戶請求時,根據(jù)session.access和session.modify標(biāo)志位設(shè)置用戶cookie和存儲session,如果sesssion.access則設(shè)置用戶cookie
如果session.modify為True或者設(shè)置setting.SESSION_SAVE_EVERY_REQUEST為True,則先獲取過期時間,如果http狀態(tài)不為500,則保存session到數(shù)據(jù)庫,并設(shè)置用戶cookie
上述可見,session的過期是靠設(shè)置cookie的過期時間來實現(xiàn)的。當(dāng)cookie過期后,用戶獲取的session_key就為空,就會為用戶重新初始化生成session。那這樣就會出現(xiàn)一個問題,舊的session_key就會越來越多,隨機(jī)生成新session_key就越難,因此django提供了一個清理的工具在management目錄下,官方的說法如下
Can be run as a cronjob or directly to clean out expired sessions (only with the database backend at the moment).sesssion加密過程
session加密只是對session value值進(jìn)行加密,加密的步驟為
序列化session value
設(shè)置加密salt為django.contrib.session+當(dāng)前類名
使用django.utils.crypto.salted_hmac進(jìn)行加密
把加密字符串進(jìn)行base64編碼,并轉(zhuǎn)換為ascii編碼,形成最終結(jié)果
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/45314.html
摘要:概述作用視圖接收請求并返回響應(yīng)本質(zhì)視圖就是一個函數(shù),被定義在文件中響應(yīng)可以是一個頁面,一個重定向,一個錯誤一個數(shù)據(jù)等等過程視圖函數(shù)對象概述服務(wù)器接收到協(xié)議的請求后,會根據(jù)報文創(chuàng)建對象視圖函數(shù)的一個形參就是對象屬性方法如果請求是通過類發(fā)起的, 概述 作用:視圖接收WEB請求并返回WEB響應(yīng)本質(zhì): 視圖就是一個python函數(shù),被定義在views.py文件中 響應(yīng): 可以是一個HTML頁面...
摘要:聲明本渣渣部分代碼參考自其實有很多代碼是不需要自己一行行碼出來,生產(chǎn)力是第一位。只有研究型人才需要生產(chǎn)代碼,作為一名渣渣拿來用是最高效的做法。程序員都有一個開源的精神,碼出來的代碼本身是希望更多的人用到,應(yīng)用到生產(chǎn)中。 聲明:本渣渣部分代碼參考自TendCode其實有很多代碼是不需要自己一行行碼出來,生產(chǎn)力是第一位。只有研究型人才需要生產(chǎn)代碼,作為一名渣渣拿來用是最高效的做法。程序員都...
摘要:聲明本渣渣部分代碼參考自其實有很多代碼是不需要自己一行行碼出來,生產(chǎn)力是第一位。只有研究型人才需要生產(chǎn)代碼,作為一名渣渣拿來用是最高效的做法。程序員都有一個開源的精神,碼出來的代碼本身是希望更多的人用到,應(yīng)用到生產(chǎn)中。 聲明:本渣渣部分代碼參考自TendCode其實有很多代碼是不需要自己一行行碼出來,生產(chǎn)力是第一位。只有研究型人才需要生產(chǎn)代碼,作為一名渣渣拿來用是最高效的做法。程序員都...
摘要:概述作用視圖接收請求并返回響應(yīng)方法就是在視圖里使用函數(shù)處理請求。 概述 作用:視圖接收WEB請求并返回WEB響應(yīng)方法:1. FBV(function base views)?就是在視圖里使用函數(shù)處理請求。 ? 2. CBV(class base views)?就是在視圖里使用類處理請求。 響應(yīng): 可以是一個HTML頁面,一個重定向,一個404錯誤、一個...
閱讀 3139·2021-11-24 09:39
閱讀 1006·2021-09-07 10:20
閱讀 2440·2021-08-23 09:45
閱讀 2319·2021-08-05 10:00
閱讀 604·2019-08-29 16:36
閱讀 866·2019-08-29 11:12
閱讀 2850·2019-08-26 11:34
閱讀 1861·2019-08-26 10:56