【一】Cookie與Session
Cookie和Session是用來在Web應用程序中跟蹤用戶會話數據的兩種常用技術。
【1】Cookie和Session的發展史
【1】Cookie的發展史:
- 1994年,網景通信公司推出了第一個瀏覽器Cookie技術。Cookie是存儲在用戶計算機上的小型文本文件,用于跟蹤用戶在網站上的活動。
- 初始版本的Cookie只能存儲很少的數據,并且沒有強制加密機制,容易被惡意用戶篡改或竊取。因此,隨著互聯網的快速發展,Cookie引起了一系列安全和隱私問題。
【2】Session的發展史:
- 由于Cookie存在的局限性,Web開發人員開始尋找更安全、可靠的替代方案。1997年,Sun Microsystems提出了基于服務器的會話管理方案,即Session。
- Session是在服務器端存儲用戶會話數據的一種技術。每當用戶訪問網站時,服務器會為其創建一個唯一的Session標識符(Session ID),并將會話數據存儲在服務器上。
- Session ID一般通過Cookie或URL參數傳遞給客戶端,用于識別用戶的會話狀態。
【2】Cookie和Session的關系:
- 在實際應用中,Cookie和Session通常結合使用。當用戶首次訪問網站時,服務器會為其分配一個唯一的Session ID,并將其存儲在Cookie中,發送給客戶端保存。
- 隨后,客戶端在每次請求中都會攜帶該Cookie,服務器通過解析Cookie中的Session ID,讀取對應的會話數據,實現用戶狀態的跟蹤和管理。
【1】總結:
- Cookie和Session是Web應用程序中常用的用戶會話跟蹤技術。
- Cookie通過在客戶端存儲小型文本文件,并將會話標識符傳遞給服務器,實現會話狀態的保持。
- 而Session則是在服務器端存儲會話數據,通過Session ID實現對用戶會話的追蹤。
- 它們的發展歷程與互聯網的發展緊密相關,為開發人員提供了更多的選擇,以保障安全性和用戶體驗的提升。
【3】Cookie與Session詳解
【1】Cookie
- 服務器保存在客戶端瀏覽器上的信息都可以稱之為cookie
- 它的表現形式一般都是k:v鍵值對(可以有多個)
【2】Session
- 保存在服務器上的信息都可以稱之為session
- 它的表現形式一般都是k:v鍵值對(可以有多個)
【3】token
- session雖然數據是保存在服務端的,但是擋不住數據量大
- 解決辦法:服務端不再保存數據
- 登陸成功之后,將一段信息加密處理(用自己獨特的加密方式進行加密)
- 將加密之后的結果拼接在信息后面,整體返回給瀏覽器保存
- 瀏覽器下次訪問的時候帶著該信息,服務端自動切取前面的一段信息再次使用自己的加密算法進行加密
- 然后用這段密文與攜帶過來的密文進行比對
【4】總結
- cookie就是保存在客戶端瀏覽器上的信息
- session就是保存在服務端上的信息
- session是基于cookie工作的(其實大部分的保存用戶狀態的操作都需要使用cookie)
【2】Django操作Cookie
- 雖然cookie是服務端告訴客戶端瀏覽器需要保存內容
- 但是客戶端瀏覽器可以選擇拒絕保存
- 如果禁止自動保存cookie
- 那么只要是需要登錄的網站都沒辦法正常登錄了
【1】三板斧-視圖函數返回
- return HttpResponse()
- return render()
- return redirect()
obj = HttpResponse("ok")
obj.set_cookie('k','v')
【2】設置cookie
def login(request, *args, **kwargs):if request.method == 'POST':username = request.POST.get("username")password = request.POST.get("password")if username == "dream" and password == "521":obj = HttpResponse("ok")obj.set_cookie('sign', 'user')return objelse:return redirect('/login/')return render(request, 'login.html')
- 取值cookie驗證
def home(request, *args, **kwargs):sign = request.COOKIES.get('sign')if sign and sign == 'user':return HttpResponse("這是home頁面")else:return redirect('/login/')
【3】取值
request.COOKIES.get('k')
【4】設置超時時間
obj.set_cookie('sign', 'user', expires=3)
obj.set_cookie('sign', 'user', max_age=3)
#設置超時時間3s到期
-
max_age
-
設置超時時間,以秒為單位
-
-
expiress
-
設置超時時間 針對IE瀏覽器使用,以秒為單位
-
【5】注銷cookie
def logout(request, *args, **kwargs):obj = redirect('/home/')# 設置超時時間 3s 到期obj.delete_cookie('sign')return obj
【6】完整版 cookie登錄注冊
def login(request, *args, **kwargs):# next_url = request.get_full_path()# print(next_url) # /login/?next_url=/home/if request.method == 'POST':username = request.POST.get("username")password = request.POST.get("password")if username == "dream" and password == "521":next_url = request.GET.get('next_url')# print(next_url) # /home/obj = redirect(next_url)obj.set_cookie('sign', 'user')return objelse:return redirect('/login/')return render(request, 'login.html')def login_auth(func):def inner(request, *args, **kwargs):# print(request.path_info) # /home/# print(request.get_full_path()) # /home/?username=111next_url = request.get_full_path() # /home/# print(next_url)# /home/sign = request.COOKIES.get('sign')if sign and sign == 'user':res = func(request, *args, **kwargs)return reselse:return redirect(f'/login/?next_url={next_url}')return inner@login_auth
def home(request, *args, **kwargs):return HttpResponse("這是home頁面")# def home(request, *args, **kwargs):
# sign = request.COOKIES.get('sign')
# if sign and sign == 'user':
# return HttpResponse("這是home頁面")
# else:
# return redirect('/login/')@login_auth
def index(request, *args, **kwargs):return HttpResponse("這是index頁面")
【3】Django操作Session
- session數據是保存在服務端的,給客戶端返回的是一個隨機字符串
- sessionid:隨機字符串
【1】設置Session
request.session['sign'] = 'user'
【2】取值session
sign = request.session.get('sign')
【3】session設置過期時間
request.session['sign'] = 'user'# 如果是數字的話就是指定 s shu# request.session.set_expiry(3)# 0 就是關閉瀏覽器后自動清除瀏覽器的sessionidrequest.session.set_expiry(0)
- 參數
- 整數
- 多少秒過期
- 日期對象
- 到指定日期失效
- 0
- 一旦退出當前瀏覽器窗口就失效
- 不寫
- 失效時間取決于Django內部全局session失效的時間
- 整數
【4】刪除session
# 刪除session方式一# request.session.delete()# 把瀏覽器和數據庫里面的session全部清除掉request.session.flush()
(1)request.session.delete()
:
只刪除服務端的
- 該方法用于刪除當前用戶的Session數據,但會保留Session的Key。
- 這意味著Session對象本身仍然存在,但其中的數據將被清空。
- 下次訪問時,如果Session沒有被重新填充,則會得到一個空的Session對象。
(2)request.session.flush()
:
服務端和客戶端都刪除
- 該方法用于完全刪除當前用戶的Session,包括Session對象和所有相關數據。
- 下次訪問時,將創建一個新的空Session對象。
【5】注意
-
session基于數據庫表才能使用的
-
必須先遷移數據庫,生成 django_session 表
-
-
session只對當次登錄有效
-
主動清除瀏覽器中本地存在的session
-
驗簽發現,沒有sessionid就會自動生成新的session
-
-
django_sessoin
表中的數據條數取決于瀏覽器 -
同一個計算機(IP地址)上同一個瀏覽器只會有一條數據生效
-
同一個計算機(IP地址)上多個瀏覽器會有多個數據生效
-
當session過期的時候,可能會出現多條數據對應一個瀏覽器
-
但是這些數據不會持久化存儲,會被定時清理掉,可以手動清除也可以代碼清除
-
-
目的是為了節省服務器數據庫資源
def login(request, *args, **kwargs):# next_url = request.get_full_path()# print(next_url) # /login/?next_url=/home/if request.method == 'POST':username = request.POST.get("username")password = request.POST.get("password")if username == "dream" and password == "521":# next_url = request.GET.get('next_url')# print(next_url) # /home/request.session['sign'] = 'user'obj = redirect('/home/')# 設置過期時間# obj.set_cookie('sign', 'user', expires=3)# obj.set_cookie('sign', 'user', max_age=3)return objelse:return redirect('/login/')return render(request, 'login.html')def login_auth(func):def inner(request, *args, **kwargs):# print(request.path_info) # /home/# print(request.get_full_path()) # /home/?username=111next_url = request.get_full_path() # /home/# print(next_url)# /home/sign = request.session.get('sign')# print(sign) # userif sign and sign == 'user':res = func(request, *args, **kwargs)return reselse:return redirect(f'/login/?next_url={next_url}')return inner@login_auth
def home(request, *args, **kwargs):return HttpResponse("這是home頁面")
【二】 CBV加裝飾器的三種方法
from django.utils.decorators import method_decorator
- 方式一:加載視圖函數上面
@method_decorator(login_auth)def get(self, request, *args, **kwargs):return HttpResponse("這是home頁面")def post(self):
- 方式二:放在類視圖上面 (放的裝飾器函數,name指定你的視圖函數里面的方法)
# @method_decorator(login_auth, name='get')
# @method_decorator(login_auth, name='post')
class UserView(View):
- 方式三 : dispactch 方法加裝飾器 : 本視圖函數內所有的視圖都需要走裝飾器
@method_decorator(login_auth)def dispatch(self, request, *args, **kwargs):# Try to dispatch to the right method; if a method doesn't exist,# defer to the error handler. Also defer to the error handler if the# request method isn't on the approved list.if request.method.lower() in self.http_method_names:handler = getattr(self, request.method.lower(), self.http_method_not_allowed)else:handler = self.http_method_not_allowedreturn handler(request, *args, **kwargs)