Cookie
介紹
由於HTTP協議是無狀態的,所以每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關係,它不會受前面的請求響應情況直接影響,也不會直接影響後面的請求響應情況。
對服務器來說,每次的請求都是全新的。
狀態可以理解爲客戶端和服務器在某次會話中產生的數據,那無狀態的就以爲這些數據不會被保留。會話中產生的數據又是我們需要保存的,也就是說要“保持狀態”。因此Cookie就是在這樣一個場景下誕生。
概念
Cookie是一個非常具體的東西,指的就是瀏覽器裏面能永久存儲的一種數據,僅僅是瀏覽器實現的一種數據存儲功能。
cookie由服務器生成,發送給瀏覽器,瀏覽器把cookie以鍵值對的形式保存到某個目錄下的文本文件內
下次訪問服務器時瀏覽器會自動攜帶這些鍵值對,以便服務器提取有用信息。
補充:
由於cookie是存在客戶端上的,所以瀏覽器加入了一些限制確保cookie不會被惡意使用,同時不會佔據太多磁盤空間,所以每個域的cookie數量是有限的。
原理
cookie的工作原理是:由服務器產生內容,瀏覽器收到請求後保存在本地;當瀏覽器再次訪問時,瀏覽器會自動帶上Cookie,這樣服務器就能通過Cookie的內容來判斷這個是“誰”了。
查看Cookie
我們使用Chrome瀏覽器,打開開發者工具。
Django中操作Cookie
設置Cookie
前提:
django返回給客戶端瀏覽器的都必須是HttpResponse對象
return HttpResponse()
return render()
return redirect()
設置:
obj = HttpResponse(...)
obj = render(request, ...)
obj.set_cookie(key,value,...)
obj.set_signed_cookie(key,value,salt='加密鹽', max_age=None, ...)
參數:
- key, 鍵
- value='', 值
- max_age=None, 超時時間
- expires=None, 超時時間(IE requires expires, so set it if hasn't been already.)
- path='/', Cookie生效的路徑,/ 表示根路徑,特殊的:根路徑的cookie可以被任何url的頁面訪問
- domain=None, Cookie生效的域名
- secure=False, https傳輸
- httponly=False 只能http協議傳輸,無法被JavaScript獲取(不是絕對,底層抓包可以獲取到也可以被覆蓋)
案例:
# 僞代碼
def lg(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'xionger' and password == '123':
# 登錄成功跳到主頁
obj = redirect('/home/')
# 設置cookie值
obj.set_cookie('name','xionger') # 瀏覽器上會保存鍵值對name:xionger
return obj
return render(request,'lg.html')
獲取Cookie
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
參數:
- default: 默認值
- salt: 加密鹽
- max_age: 後臺控制過期時間
案例:
# 僞代碼
def home(request):
# 先校驗客戶端cookie中有沒有寫入的鍵值對
if request.COOKIES.get('name'):
return render(request, 'home.html')
return HttpResponse('主頁只能登錄才能看')
刪除Cookie
obj.delete_cookie('key')
案例:
def logout(request):
obj = redirect('/lg/')
obj.delete_cookie('name') # 刪除瀏覽器上的cookie鍵值對
# 從定向到lg頁面
return obj
Cookie版登陸
def lg(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'xionger' and password == '123':
# 先獲取url中get請求攜帶的參數
target_url = request.GET.get('next')
# 判斷用戶是直接訪問登錄頁面還是從其他頁面跳過來的
if target_url:
obj = redirect(target_url)
else:
# # 如果用戶直接訪問的登陸頁面 那麼登陸完成之後 直接跳到網站的首頁
obj = redirect('/home/')
# 設置cookie值
obj.set_cookie('name','xionger') # 瀏覽器上會保存鍵值對name:xionger
return obj
return render(request,'lg.html')
Session
介紹
Cookie雖然在一定程度上解決了“保持狀態”的需求,但是由於Cookie本身最大支持4096字節,以及Cookie本身保存在客戶端,可能被攔截或竊取,因此就需要有一種新的東西,它能支持更多的字節,並且他保存在服務器,有較高的安全性。這就是Session。
問題來了,基於HTTP協議的無狀態特徵,服務器根本就不知道訪問者是“誰”。那麼上述的Cookie就起到橋接的作用。
我們可以給每個客戶端的Cookie分配一個唯一的id,這樣用戶在訪問時,通過Cookie,服務器就知道來的人是“誰”。然後我們再根據不同的Cookie的id,在服務器上保存一段時間的私密資料,如“賬號密碼”等等。
- session是保存在服務端的數據(本質是鍵值對)
- session的應用:依賴於cookie
- session的作用:保持會話(web網站)
- session的好處:敏感信息不會直接給客戶端,客戶端拿到的是session值(隨機字符串)
補充: Cookie和Session其實是共通性的東西,不限於語言和框架。
Django中操作Session
設置Session
request.session['key'] = 'value'
發生了三件事:
- 1.django 內部自動生成一個隨機字符串
- 2.將隨機字符串和你要保存的數據 寫入django_session表中(現在內存中生成一個緩存記錄 等到經過中間件的時候纔會執行)
- 3.將產生的隨機字符串發送給瀏覽器寫入cookie
案例:
def set_session(request):
request.session['name'] = 'xionger'
request.session.set_ecpiry(30)
return HttpResponse('設置session')
ps:設置的{name:xionger} 存放放到 django_session表中的session_data中
session值(隨機字符串):{name:'xionger',password:123,...}
ps:瀏覽器會設置一個鍵爲sessionid來存放session值(即隨機字符串) 如: sessionid: k7z2t28sz15ms1ph...
獲取Session
request.session.get('key')
# 有返回值,若對應的key沒有值,則返回None,設置的時候key是什麼,取的時候key就是什麼
發生了三件事:
- 1.django內部會自動從請求信息中獲取到隨機字符串
- 2.拿着隨機字符串去django_session表中比對
- 3.一旦對應上了就將對應的數據解析出來放到request.session中
設置Session與獲取Session案例:
# 設置Session
def login(request):
if request.method == 'POST':
name = request.POST.get('username')
pwd = request.POST.get('password')
if name == 'xionger' and pwd == 123:
# 1. 生成隨機的字符串
# 2. 通過cookie發送給客戶端
# 3. 服務端保存{隨機字符串:{name:xionger,...}}
request.session['name'] = 'xionger'
return redirect('/index/')
return render(request,'login.html')
# 獲取Session
def index(request):
# 1. 獲取客戶端cookie中的隨機字符串
# 2. 取session中查看有沒有隨機字符串
# 3. 取session對應的key的value中查看是否有name
v = request.session.get('name')
if v:
return HttpResponse('登錄成功:%s'%v) # >>> 登錄成功xionger
else:
return HttpResponse('請先登錄')
刪除Session
request.session.delete()
# 刪除當前會話的所有Session數據 (session_data中的鍵值對)
request.session.flush()
# 刪除當前的會話數據並刪除會話的Cookie。這用於確保前面的會話數據不可以再次被用戶的瀏覽器訪問
# 例如,django.contrib.auth.logout() 函數中就會調用它。
設置會話Session和Cookie的超時時間
request.session.set_ecpiry(value)
- * 如果value是個整數,session會在些秒數後失效。
- * 如果value是個datatime或timedelta,session就會在這個時間後失效。
- * 如果value是0,用戶關閉瀏覽器session就會失效。
- * 如果value是None,session會依賴全局session失效策略。
注意:django默認的session存活時間是兩週(14天)
Session流程解析
補充:
執行了數據庫遷移命令就會生成django_session表,若報下面的錯只需要執行數據庫遷移命令即可
django_session表的其他用途
你在後期可以將一些數據保存到session表中,保存的數據 可以在後端任意位置獲取到