目錄
- 簡介
- Cookie出現原因
- 實現原理
- Cookie操作
- cookie+session
- 總結:
簡介
- 前幾節的介紹中我們已經有能力制作一個登陸頁面,在驗證了用戶名和密碼的正確性后跳轉到后臺的頁面。但是測試后也發現,如果繞過登陸頁面。直接輸入后臺的url地址也可以直接訪問的。這個顯然是不合理的。其實我們缺失的就是cookie和session配合的驗證。有了這個驗證過程,我們就可以實現和其他網站一樣必須登錄才能進入后臺頁面了。
- 先說一下這種認證的機制。每當我們使用一款瀏覽器訪問一個登陸頁面的時候,一旦我們通過了認證。 服務器端就會發送一組 隨機唯一 的字符串到瀏覽器端 ,這個被存儲在瀏覽端的東西就叫 cookie 。而服務器端也會自己存儲一下用戶當前的狀態,比如login=true,username=hahaha之類的用戶信息。但是這種存儲是以 字典形式存儲 的,字典的唯一key就是剛才發給用戶的唯一的cookie值。因為每個cookie都是唯一的,所以我們在電腦上換個瀏覽器再登陸同一個網站也需要再次驗證。
Cookie出現原因
-
cookie不屬于http協議范圍,由于http協議無法保持狀態,但實際情況,我們卻又需要“保持狀態”,因此cookie就是在這樣一個場景下誕生。
cookie的工作原理是:由服務器產生內容,瀏覽器收到請求后保存在本地;當瀏覽器再次訪問時,瀏覽器會自動帶上cookie,這樣服務器就能通過cookie的內容來判斷這個是“誰”了。 -
cookie雖然在一定程度上解決了“保持狀態”的需求,但是由于cookie本身最大支持4096字節,以及cookie本身保存在客戶端,可能被攔截或竊取,因此就需要有一種新的東西,它能支持更多的字節,并且他保存在服務器,有較高的安全性。這就是session。
問題來了,基于http協議的無狀態特征,服務器根本就不知道訪問者是“誰”。那么上述的cookie就起到橋接的作用。
我們可以給每個客戶端的cookie分配一個唯一的id,這樣用戶在訪問時,通過cookie,服務器就知道來的人是“誰”。然后我們再根據不同的cookie的id,在服務器上保存一段時間的私密資料,如“賬號密碼”等等。 -
總結而言:cookie彌補了http無狀態的不足,讓服務器知道來的人是“誰”;但是cookie以文本的形式保存在本地,自身安全性較差;所以我們就通過cookie識別不同的用戶,對應的在session里保存私密的信息以及超過4096字節的文本。
-
另外,上述所說的cookie和session其實是共通性的東西,不限于語言和框架
實現原理
HTTP被設計為”無狀態”,每次請求都處于相同的空間中。 在一次請求和下一次請求之間沒有任何狀態保持,我們無法根據請求的任何方面(IP地址,用戶代理等)來識別來自同一人的連續請求。上圖很明顯的展示了Django的session與cookie的實現原理。服務器會生成兩份相同的cookie字符串,一份保存在本地,一份發向請求的瀏覽器。瀏覽器將收到的cookie字符串保存下來,當下次再發請求時,會將信息與這段cookie一同發送到服務器,服務器得到這段cookie會與本地保存的那份判斷是否相同,如果相同就表示用戶已經登錄成功,保存用戶登錄成功的狀態。Django的session保存在數據庫中的數據相當于一個大字典,key為cookie的字符串,value仍是一個字典,字典的key和value為用戶設置的相關信息。這樣就可以方便的存取session里面的信息。
Cookie操作
參數 | 描述 |
---|---|
max_age | cookie生效的時間,單位是秒 |
expires | 具體過期日期 |
path | 指定那個url可以訪問到cookie;‘/’是所有; |
domain | (None代表當前域名):指定那個域名以及它下面的二級域名(子域名)可以訪問這個cookie |
secure | 默認值為False;https安全相關 |
httponly | 默認值為False;限制只能通過http傳輸,JS無法在傳輸中獲取和修改 |
---------------------------------------views.py-------------------------------------------------
def login(request):
print(request.COOKIES)
if request.method == "POST":
name = request.POST.get("name")
pwd = request.POST.get("pwd")
if name == "root" and pwd == "123456":
red = redirect("/app2/index/")
red.set_cookie("test1","cookie1") # 如果登陸成功,設置cookie值,保存登錄狀態
# 登錄成功就將url重定向到后臺的url
return red
#登錄不成功或第一訪問就停留在登錄頁面
return render(request,"login.html")
def index(request):
print(request.COOKIES.get("test1",None))
if request.COOKIES.get("test1",None) == "cookie1":
#如果有Cookie緩存,跳轉登陸后的界面,否者返回到登錄頁面
return render(request,"index.html")
else :
return render(request,"login.html")
cookie+session
1、cookie引入session:
-
cookie看似解決了HTTP(短連接、無狀態)的會話保持問題,但把全部用戶數據保存在客戶端,存在安全隱患,
-
于是cookie+session出現了!我們可以 把關于用戶的數據保存在服務端,在客戶端cookie里加一個sessionID(隨機字符串),
-
基于以上原因:cook+session組合就此作古了單單使用cookie做會話保持的方式;
2、 cookie+session的工作流程 :
-
(1)、當用戶來訪問服務端時,服務端生成一個隨機字符串;
-
(2)、當用戶登錄成功后 把 {sessionID :隨機字符串} 組織成鍵值對 加到 cookie里發送給用戶;
-
(3)、服務器以發送給客戶端 cookie中的隨機字符串做鍵,用戶信息做值,保存用戶信息;
from django.shortcuts import render, redirect, HttpResponse
# Create your views here.
def login(request):
print(request.COOKIES)
print(request.session)
if request.method == "POST":
name = request.POST.get("name")
pwd = request.POST.get("pwd")
if name == "root" and pwd == "123456":
request.session["is_login"] = True
request.session["username"] = name
return redirect("/app2/index/")
return render(request,"login.html")
def index(request):
if request.session.get("is_login"):
return render(request,"index.html")
else :
return redirect("/app2/login/")
總結:
一、操作Cookie
-
獲取cookie:request.COOKIES[key]
-
設置cookie:response.set_cookie(key,value)
由于cookie保存在客戶端的電腦上,所以,jquery也可以操作cookie。
$.cookie("list_pager_num", 30,{ path: '/' });
二、操作Session(session默認在服務器端保存15天)
-
獲取session:request.session[key]
-
設置session:reqeust.session[key] = value
-
刪除session:del request.session[key]
(這個刪除其實就是把數據庫的session_data更新為一個其他的值了,并沒有立即刪除)
request.session.set_expiry(value)
* 如果value是個整數,session會在些秒數后失效。
* 如果value是個datatime或timedelta,session就會在這個時間后失效。
* 如果value是0,用戶關閉瀏覽器session就會失效。
* 如果value是None,session會依賴全局session失效策略。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
