2021-05-12 14:32:11
day55:django:cookie&session
目錄
Cookie
1.Cookie前戲
HTTP協議的兩個特點
1.無連線
將協議設計為請求時建連線、請求完釋放連線,以儘快將資源釋放出來服務其他客戶端。
2.無狀態
什麼是無狀態?
無狀態的意思是每次請求都是獨立的,
它的執行情況和結果與前面的請求和之後的請求都無直接關係,
它不會受前面的請求響應情況直接影響,
也不會直接影響後面的請求響應情況
簡單的來說:無狀態是指伺服器不知道客戶端是什麼狀態。
對於無狀態的解釋
要明白,這句話的含義是指在說明,http協議作為技術背景的web應用程式請求——應答模式是無狀態的,這個事實基本不會發生改變,也不會因為加入cookies、session機制而變成有狀態的。
要明白,這種前後因果關係:“我們要實現的是一種web應用,實現這種應用的協議我們選擇了http這種本質上是無狀態的通訊協議。
但是事實上,我們需要我們的web應用是有狀態的。所以我們加入了cookies、session等機制去實現有狀態的web應用。
2.Cookie的引入
1.cookie的引入
因為http無狀態,所以出現了cookie,cookie是一種瀏覽器技術
2.cookie能做什麼?
1.瀏覽器訪問服務端,帶著一個空的cookie,
2.然後由伺服器產生內容,瀏覽器收到相應後儲存在本地;
3.當瀏覽器再次訪問時,瀏覽器會自動帶上Cookie,這樣伺服器就能通過Cookie的內容來判斷這個是“誰”了。
3.cookie規範
- Cookie大小上限為4KB;
- 一個伺服器最多在客戶端瀏覽器上儲存20個Cookie;
- 一個瀏覽器最多儲存300個Cookie,因為一個瀏覽器可以訪問多個伺服器。
上面的資料只是HTTP的Cookie規範,但在瀏覽器大戰的今天,一些瀏覽器為了打敗對手,為了展現自己的能力起見,可能對Cookie規範“擴展”了一些,例如每個Cookie的大小為8KB,最多可儲存500個Cookie等!但也不會出現把你硬碟佔滿的可能!
注意,不同瀏覽器之間是不共用Cookie的。也就是說在你使用IE訪問伺服器時,伺服器會把Cookie發給IE,然後由IE儲存起來,當你在使用FireFox訪問伺服器時,不可能把IE儲存的Cookie傳送給伺服器。
4.cookie和HTTP頭
Cookie是通過HTTP請求和響應頭在客戶端和伺服器端傳遞的:
- Cookie:請求頭,客戶端傳送給伺服器端;
- 格式:Cookie: a=A; b=B; c=C。即多個Cookie用分號離開;
- Set-Cookie:響應頭,伺服器端傳送給客戶端;
- 格式:一個Cookie物件一個Set-Cookie: Set-Cookie: a=A Set-Cookie: b=B Set-Cookie: c=C
5.cookie的覆蓋
如果伺服器端傳送重複的Cookie那麼會覆蓋原有的Cookie,例如客戶端的第一個請求伺服器端傳送的Cookie是:Set-Cookie: a=A;第二請求伺服器端傳送的是:Set-Cookie: a=AA,那麼客戶端只留下一個Cookie,即:a=AA。
3.django中操作cookie
cookie的獲取/設定/修改/刪除
1.獲取cookie
# 獲取cookie request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) #帶簽名的值 ''' 參數: default: 預設值 salt: 加密鹽 max_age: 後臺控制過期時間 '''
2.設定cookie
# 設定cookie '''cookie的獲取都是基於request物件的''' '''cookie的設定都是基於HttpResponse物件的''' rep = HttpResponse(...) rep = render(request, ...) rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt='加密鹽', max_age=None, ...)
3.修改cookie
# 修改cookie ret.set_cookie('username', 'xxx') #相同的鍵設定不同的值就是修改
4.刪除cookie
# 刪除cookie ret.delete_cookie('username')
cookie參數的意義
key # 鍵 value='' # 值 max_age=None # 超時時間,單位為秒 5表示5秒後失效 expires=None # 超時時間(IE requires expires,so set it if hasn't been already.)值為時間日期類型資料 path='/' # Cookie生效的路徑,/ 表示根路徑,特殊的:根路徑的cookie可以被任何url的頁面訪問 domain=None # Cookie生效的域名 secure=True # https傳輸 httponly=False # 只能http協議傳輸,無法被JavaScript獲取(不是絕對,底層抓包可以獲取到也可以被覆蓋)
Session
1.cookie的侷限性
1.cookie是明文儲存的
2.cookie的大小限制
Cookie大小上限為4KB;
一個伺服器最多在客戶端瀏覽器上儲存20個Cookie;
一個瀏覽器最多儲存300個Cookie,因為一個瀏覽器可以訪問多個伺服器。
2.session技術
session比cookie的強大之處
Cookie雖然在一定程度上解決了“保持狀態”的需求,但是由於Cookie本身最大支援4096位元組,以及Cookie本身儲存在客戶端,可能被攔截或竊取,
因此就需要有一種新的東西,它能支援更多的位元組,並且他儲存在伺服器,有較高的安全性。這就是Session。
cookie的橋接作用
問題來了,基於HTTP協議的無狀態特徵,伺服器根本就不知道訪問者是“誰”。那麼上述的Cookie就起到橋接的作用。
我們可以給每個客戶端的Cookie分配一個唯一的id,這樣使用者在訪問時,通過Cookie,伺服器就知道來的人是“誰”。
然後我們再根據不同的Cookie的id,在伺服器上儲存一段時間的私密資料,如“賬號密碼”等等。
cookie和session各自實現的功能總結
總結而言:Cookie彌補了HTTP無狀態的不足,讓伺服器知道來的人是“誰”;
但是Cookie以文字的形式儲存在本地,自身安全性較差;
所以我們就通過Cookie識別不同的使用者,對應的在Session裡儲存私密的資訊以及超過4096位元組的文字。
3.django操作session
# 設定session request.session['k1'] = 123 request.session.setdefault('k1',123) # 獲取session request.session['k1'] request.session.get('k1',None) # 刪除session del request.session['k1'] # 清空session request.session.flush()
4.Session詳細流程解析
5.session例項分析
這是一段登入的檢視函數,在函數中新增兩個session,在新增session時,做了三件事
def login(request): if request.method == 'GET': return render(request, 'login.html') else: uname = request.POST.get('username') if uname == 'root' or uname=='abc': request.session['is_login'] = True request.session['username'] = uname # request.session # 1 生成一個隨機字元串 # 2 將隨機字元串放到cookie中,名稱為sessionid # 3 將設定的session資料,序列化+加密,儲存到了django-session表中 return redirect('/home/') else: return redirect('/login/')
這是一段登出的檢視函數,這個時候我們要刪除session,在刪除session時,做了兩件事
def logout(requset): requset.session.flush() # 1 刪除cookie中的資料 # 2 刪除資料庫中django-session表中的記錄 return redirect('/login/')
這是一個基於session的登入認證中介軟體,這個時候我們要修改session,在修改session,做了三件事
# 基於session的登入認證中介軟體 class LoginAuth(MiddlewareMixin): white_list = ['/login/', ] # 白名單 def process_request(self,request): path = request.path # 獲取當前請求路徑 if path not in self.white_list: # 如果路徑不在白名單內 is_login = request.session.get('is_login') # 獲取session中is_login的值 # request.session['is_login'] # 1 取出請求中cookie鍵為sessionid的值 # 2 通過這個值到django-session表中獲取資料 # 3 將資料解密並且反序列化得到原來的資料 if is_login != True: return redirect('/login/')
6.對於cookie和session的總結
...
django外部指令碼呼叫django環境
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_cookie.settings") import django django.setup() from app01 import models models.Book.objects.create( title='xxx', price=200, )
相關文章