深刻一下Django的用戶認證和cache

深刻一下Django的用戶認證和cache

用戶認證

首先明白一個概念,http協議是無狀態的,也就是每一次交互都是獨立的,那如何讓服務器和客戶端進行有狀態的交互呢,如今較爲常見的方法就是讓客戶端在發送請求的時候帶上服務器給他的身份證(特定的cookie),以此來識別來訪者的身份。數據庫

關於session和cookie

這二者的做用都是儲存數據,以此方便服務器和客戶端進行有狀態的交互。而後cookie是確實存在於客戶端的瀏覽器中,而session信息則是保持在服務器中,這二者之間的聯繫就是,這個sessionID是存放到cookie中的,每次請求,客戶端都會帶上這個sessionID來告訴服務器我是誰。django

具體實現

經過上面講的,實現用戶認證,實際上就是維護一個有狀態的交互(會話)。Django已經內置實現了session,只須要在中間件中啓用session模塊(這是默認啓用的),那麼就能夠經過操做request對象的session屬性,來控制這個有狀態的交互。瀏覽器

通常的流程就像這樣:緩存

sequenceDiagram loop onetime 用戶端->>服務器:用戶登錄,填表單發送post請求 Note right of 服務器:服務器驗證 服務器->>用戶端:返回的響應中會包含sessionID end loop onetime 用戶端->>服務器:發送的請求中帶着這個sessionID Note right of 服務器:根據請求中的sessionID去查找儲存在服務器上的session 服務器->>用戶端:返回特定的內容 end

實現細節

怎麼驗證

當中間件啓用authsession後,直接調用request.user.is_authenticated就能夠知道這個請求是否驗證的了。服務器

####保存方式cookie

能夠在配置中指定SESSION_ENGINE,能夠選擇放在數據庫、緩存、文件或者cookie中。session

使用方式

在視圖文件view.py中,能夠直接把request.session當成字典來使用。oop

若是想在其餘地方使用session的內容,也能夠直接實例化一個數據庫的鏈接(SessionStore)來進行交互。post

過時設置

針對單個sessionset_expiry()來設置過時時間,也能夠經過在配置中SESSION_EXPIRE_AT_BROWSER_CLOSE選擇是否在瀏覽器關閉時清除會話信息,這都取決於具體的業務需求。code

刪除會話存儲信息

咱們知道每維護一個會話,就要存儲一行數據,也就是說當會話愈來愈多,所要存儲的數據也會愈來愈多。若是選擇會話的存儲方式爲數據庫或者文件系統,Django會在用戶登出時自動刪除掉對應的會話數據,可是若是用戶不主動登出,那麼就算過了過時時間,Django也不會去刪除對應的會話數據,須要咱們手動去執行cleansessions才行,文檔是建議咱們用一個定時任務cron來執行這一步。若是存儲方式爲緩存則沒有這個問題,Django會自動刪除過時會話數據。至於存儲方式選擇爲cookie的就更加無所謂了,由於數據都只在用戶端。

Cache

以前大概介紹過怎麼使用Django的緩存系統,如今更深刻一點介紹其使用方式。

以前使用的緩存邏輯是很粗魯地直接整頁緩存,其特色就是每一個用戶看到的緩存頁面都是同樣的,緩存有效時間內,一份緩存就能夠知足全部請求,可是缺點就是不能根據特定用戶返回特定頁面。

使用Vary頭來區分

patch_vary_header來指定以響應頭部的特定信息來區分不一樣的緩存,好比patch_vary_header(response, 'cookie')就會根據cookie的信息來選擇返回的哪個緩存。

使用模版文件的緩存標籤

能夠選擇緩存模版文件(template)中的某部分,也就是生成最終頁面時,一部分頁面來自緩存,一部分頁面即時生成。

直接與緩存數據交互

能夠實例化一個與緩存系統的鏈接,以此來存取一些更耗時的操做結果。例若有一個很複雜的數據查找,能夠將結果存到緩存中,在緩存有效時間內,就能夠用一次簡單的查找來代替那個複雜的查找。

返回304

能夠在響應頭部加上ETaglast-modified,用戶端在下次請求同一個頁面時會帶上這兩個信息,服務器會先校驗這兩個信息,若是頁面沒發生變化,則直接返回一個狀態碼爲304,body爲空的響應,告訴瀏覽器直接使用本地緩存便可。Django提供了一箇中間件ConditionalGetMiddleware來幫助咱們驗證這兩個信息。或者能夠本身手動在響應頭部添加相關信息,和手動驗證。

小小總結

上述的前三種方式,服務器都是或多或少先生成一個(部分)緩存頁面,而後在客戶端下次請求相同頁面時,利用緩存來生成頁面並返回(或者直接返回緩存頁面,反正就不是即時生成頁面);而最後一種方式,則是服務器校驗請求的頭部信息,看客戶端所請求的頁面是否在其上一次請求後有發生變化,若是沒有,則返回一個304,說你直接使用本地的緩存就能夠了。

相關文章
相關標籤/搜索