Django中的Cookie--實現登錄
Cookie
Cookie 是什么
保存在瀏覽器端的鍵值對,讓服務器提取有用的信息。
為什么要有 Cookie
因為HTTP請求是無狀態的。
無狀態的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之后的請求都無直接關系,它不會受前面的請求響應情況直接影響,也不會直接影響后面的請求響應情況。
狀態可以理解為客戶端和服務器在某次會話中產生的數據,那無狀態的就以為這些數據不會被保留。會話中產生的數據又是我們需要保存的,也就是說要“保持狀態”。因此Cookie就是在這樣一個場景下誕生。
Cookie 的原理
服務端可以在返回響應的時候 做手腳
在瀏覽器上寫入鍵值對(Cookie)
瀏覽器發送請求的時候會自動攜帶該網站保存在我瀏覽器的鍵值對(Cookie)
Chrome 上查看 Cookie

查看Cookie
Django 中操作 Cookie
設置 Cookie
只有響應對象才能設置 Cookie
# 響應對象
rep = HttpResponse(...)
rep = render(request, ...)
rep = redirect(...)
# 不加密方式設置Cookie
rep.set_cookie(key,value,...)
# 加密方式設置Cookie
rep.set_signed_cookie(key,value,salt='加密鹽',...)
參數
- 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 獲取(不是絕對,底層抓包可以獲取到也可以被覆蓋)
獲取 Cookie
- 不加密的 Cookie 獲取:
request.COOKIES['key'] request.COOKIES.get('key')
- 加密的 Cookie 獲取
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
- default: 默認值
- salt: 加密鹽
- max_age: 后台控制過期時間
刪除 Cookie
刪除 Cookie 操作大多是在注銷時用的,也是 通過響應對象刪除。
def logout(request):
# 刪除cookie,操作的是響應對象,最后需要返回
rep = redirect("/app01/login/")
rep.delete_cookie("is_login")
return rep
Cookie 版登錄代碼
from django.shortcuts import render, redirect
# 導入用於裝飾器修復技術的包
from functools import wraps
# Create your views here.
# 裝飾器函數,用來判斷是否登錄
def check_login(func):
@wraps(func) # 裝飾器修復技術
def inner(request, *args, **kwargs):
ret = request.get_signed_cookie("is_login", default="0", salt="ban")
if ret == "1":
# 已經登錄,繼續執行
return func(request, *args, **kwargs)
# 沒有登錄過
else:
# ** 即使登錄成功也只能跳轉到home頁面,現在通過在URL中加上next指定跳轉的頁面
# 獲取當前訪問的URL
next_url = request.path_info
return redirect("/app01/login/?next={}".format(next_url))
return inner
def login(request):
if request.method == "POST":
username = request.POST.get("username")
pwd = request.POST.get("pwd")
next_url = request.GET.get("next")
if username == "alex" and pwd == "dsb":
# return redirect("/home/")
# 服務器返回的響應對象
# 通過URL中的next參數指定跳轉的頁面,如果為空,默認跳轉到home頁面
if next_url:
rep = redirect(next_url)
else:
print("ban")
rep = redirect("/app01/home/")
# 1. 設置cookie
# rep.set_cookie("is_login", "1")
# 2. 設置加鹽cookie,max_age是cookie的生存時間
rep.set_signed_cookie("is_login", "1", salt="ban", max_age=100)
return rep
return render(request, "app01/login.html")
def home(request):
# 獲取cookie並判斷
# if request.COOKIES.get("is_login", 0) == "1":
# 獲取加鹽cookie並判斷
ret = request.get_signed_cookie("is_login", default="0", salt="ban")
if ret == "1":
return render(request, "app01/home.html")
else:
return redirect("/app01/login/")
# 注銷函數
def logout(request):
# 刪除cookie,操作的是響應對象,最后需要返回
rep = redirect("/app01/login/")
rep.delete_cookie("is_login")
return rep
@check_login
def index(request):
return render(request, "app01/index.html")
參考:https://www.cnblogs.com/liwenzhou/p/8343243.html
GitHub地址:https://github.com/protea-ban/oldboy/tree/master/s9day71/xiawu