day56 cookie和session和中間件
Cookie和session
Cookie初識
Cookie的由來
大家都知道HTTP協定是無狀态的。
無狀态的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關系,它不會受前面的請求響應情況直接影響,也不會直接影響後面的請求響應情況。
一句有意思的話來描述就是人生隻如初見,對伺服器來說,每次的請求都是全新的。
狀态可以了解為用戶端和伺服器在某次會話中産生的資料,那無狀态的就以為這些資料不會被保留。會話中産生的資料又是我們需要儲存的,也就是說要“保持狀态”。是以Cookie就是在這樣一個場景下誕生。
并且還有一個問題就是,你登陸我的網站的時候,我沒法确定你是不是登陸了,之前我們學的django,雖然寫了很多頁面,但是使用者不用登陸都是可以看所有網頁的,隻要他知道網址就行,但是我們為了自己的安全機制,我們是不是要做驗證啊,通路哪一個網址,都要驗證使用者的身份,但是還有保證什麼呢,使用者登陸過之後,還要保證登陸了的使用者不需要再重複登陸,就能夠通路我網站的其他的網址的頁面,對不對,但是http無狀态啊,怎麼保證這個事情呢?此時就要找cookie了。
什麼是Cookie
首先來講,cookie是浏覽器的技術,Cookie具體指的是一段小資訊,它是伺服器發送出來存儲在浏覽器上的一組組鍵值對,可以了解為服務端給用戶端的一個小甜點,下次通路伺服器時浏覽器會自動攜帶這些鍵值對,以便伺服器提取有用資訊。
Cookie的原理
Cookie的工作原理是:浏覽器通路服務端,帶着一個空的cookie,然後由伺服器産生内容,浏覽器收到相應後儲存在本地;當浏覽器再次通路時,浏覽器會自動帶上Cookie,這樣伺服器就能通過Cookie的内容來判斷這個是“誰”了。
Http協定特點
- 無狀态,無連接配接(HTTP 1.1 版本出現了短連接配接)
- 格式:請求行 – 請求頭 – 空行 – 請求資料
django 操作cookie
擷取cookie:
擷取簽名cookie(不常用):
設定cookie:
設定簽名cookie(不常用):
設定cookie逾時時間和過期日期:
ret.set_cookie('is_login',True,max_age=5) # 逾時時間 秒數
ret.set_cookie('is_login',True,expires=datetime.datetime.now() + datetime.timedelta(days=7)) #過期日期
删除cookie:
session的優勢
- 借助于cookie進行傳輸
- 非明文顯示
- 長度不限
- Django為我們提供了十分友善的session使用接口,隻需要簡單地幾條指令就可以實作session的設定、擷取和清空。
設定session
設定session的指令包括三個步驟:
- 生成随機字元串
- 放到cookie中進行傳輸
- 将随機字元串和對應資料儲存到自己服務端的資料庫中,django-session表
擷取session
這簡簡單單的一條指令,其實隐含了大約三個擷取session的步驟,也就是設定session的逆過程:
# 1 取出cookie中的session随機字元串{'sessionid':'asdfasfpoaijsdgihsdj'}
xx = request.COOKIES.get('sessionid')
# 2 到資料庫中查詢這個sessionid對應的那條記錄
data = select session_data from django_session where session_key = xx;
# 3 拿出記錄中的session_data資料部分進行解密,并取出資料
dic = sss(data) -- {'is_login':True}
dic.get('is_login') -- True
登出session
@func
def logout(request):
request.session.flush() # 删除session
return redirect('login')
session.flush()
指令是将session登出,主要是兩個步驟:
- 删除cookie中的sessionid那個鍵值對
- 删除了資料庫中的這條記錄
Cookie 和 session 的總結與對比
cookie:
- 保持會話,使使用者不需要重複地去登入
- 有大小限制
- 有個數限制
- Cookie總大小上限為4KB
- 一個伺服器最多在用戶端浏覽器上儲存20個Cookie
- 一個浏覽器最多儲存300個Cookie,因為一個浏覽器可以通路多個伺服器
session:
- 比cookie面上安全一些
- session沒有大小限制
- 可以配置多個存儲方案,可以配置到緩存中
中間件
自定義中間件
# 第一步,在應用下面建立一個檔案夾,名字随便,比如mymiddleware,在這個檔案夾下建立 一個py檔案,名字随便,比如叫做xx.py
# 第二步:在xx.py檔案中定義類,寫法如下
from django.shortcuts import redirect,HttpResponse,render
from django.utils.deprecation import MiddlewareMixin #引入django這個類
class Auth(MiddlewareMixin): #繼承這個類
# 白名單 認證白名單
white_list = ['/login/',]
def process_request(self,request): #想對請求進行統一的處理,那麼就定義一個process_request方法
# 如果方法傳回值是None,那就通過了這個方法的認證或者處理,如果傳回的值HttpResponse對象,那麼請求到這裡就結束了,直接傳回給了浏覽器
if request.path in self.white_list:
pass
else:
is_login = request.session.get('is_login')
if is_login == True:
pass
else:
return HttpResponse('滾犢子!!')
# 第三步,settings配置檔案中寫上這個類的路徑
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'app01.mymiddleware.xx.Auth',
]
process_response方法
def process_response(self,request,response):
'''
:param request:
:param response: 就是視圖的傳回值(HttpResponse對象)
:return:
'''
# print(response)
return response
process_view以及執行順序
from django.shortcuts import redirect,HttpResponse,render
# 引入django的子產品
from django.utils.deprecation import MiddlewareMixin
class MD1(MiddlewareMixin):
def process_request(self,request):
print('MD1--process_request')
return HttpResponse('xxxlpapsjdfoajsdfh')
def process_response(self, request,response):
print('MD1--process_response')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print('MD1---',view_func.__name__)
# view_func就是url對應那個views裡面的視圖函數,視圖函數的參數view_args, view_kwargs
class MD2(MiddlewareMixin):
def process_request(self, request):
print('MD2--process_request')
def process_response(self, request, response):
print('MD2--process_response')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print('MD2---',view_func.__name__)