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