Session與Cookie
cookie
服務端保存在客戶端瀏覽器上的信息都可以教cookie
表現形式一般是k:v鍵值對(可以多個)
?
優化:
隨機字符串1:用戶1相關信息
隨機字符串2:用戶2相關信息
?
session
數據是保存在服務端
表現形式一般是k:v鍵值對
session是基于cookie工作。(大部分保存用戶狀態的操作都需要cookie)
?
token
session雖然數據保存在服務端,但是禁不住數據量大。
服務端不再保存數據
????? 登陸成功后,將一段信息進行加密處理(加密算法是自己開發)
????? 將加密后的結果拼在信息后面,整體返回給瀏覽器保存
???? 瀏覽器下次訪問帶著該數據信息,服務端自動切去前面一段信息再次使用自己加密算法
??? 跟瀏覽器尾部的密文進行對比
?
jwt認證
三段信息,后續補充。。。。
?
Cookie操作
瀏覽器禁用cookie,網站保存賬戶功能失效。
獲取Cookie
request.COOKIES當成一個字典
request.COOKIES['key'] 或者 request.COOKIES.get('username') username是key
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
參數:
- default: 默認值
- salt: 加密鹽
- max_age: 后臺控制過期時間
設置Cookie
一定要用HttpResponse類直接或者間接產生的對象
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獲取(不是絕對,底層抓包可以獲取到也可以被覆蓋
?
刪除Cookie
obj = HttpResponse(...)
obj = render(request, ...)
obj.delete_cookie("user") # 刪除用戶瀏覽器上之前設置的usercookie值
Cookie版登陸校驗
def check_login(func):@wraps(func)def inner(request, *args, **kwargs):next_url = request.get_full_path()if request.get_signed_cookie("login", salt="SSS", default=None) == "yes":# 已經登錄的用戶...return func(request, *args, **kwargs)else:# 沒有登錄的用戶,跳轉剛到登錄頁面return redirect("/login/?next={}".format(next_url))return innerdef login(request):if request.method == "POST":username = request.POST.get("username")passwd = request.POST.get("password")if username == "xxx" and passwd == "dashabi":next_url = request.GET.get("next")if next_url and next_url != "/logout/":response = redirect(next_url)else:response = redirect("/class_list/")response.set_signed_cookie("login", "yes", salt="SSS")return responsereturn render(request, "login.html")@check_login
def home(request):return HttpResponse("home頁面,只有登陸了才能查看~")
?
session操作
note:
1. django 默認存放django_session。需要遷移命令生成表格,才能存放session,也可以保存到其他地方。
2. django中默認的session超時時間為14天
request.session['key'] = value 1.django內部會自動生成一個隨機字符串2.去django_session表中存儲數據 鍵就是隨機字符串 值是要保存的數據(中間件干的)3.將生成好的隨機字符串返回給客戶端瀏覽器 瀏覽器保存鍵值對sessionid 隨機字符串 request.session.get('key')1.django會自動取瀏覽器的cookie查找sessionid鍵值對 獲取隨機字符串2.拿著該隨機字符串取django_session表中比對數據3.如果比對上了 就將隨機字符串對應的數據獲取出來并封裝到request.session供用戶調用
?
1. django session表中的數據條數取決于瀏覽器
??? 同一臺計算機同一個瀏覽器指揮有一條
?
設置session與cookie的超時時間
?
request.session.set_expiry(value)* 整數,session會在些秒數后失效。* datatime或timedelta,session就會在這個時間后失效。* 0,用戶關閉瀏覽器session就會失效。* 不寫(none),session會依賴全局session失效策略。
?
刪除session
request.session.flush() #瀏覽器和服務端都清空,推薦使用。
?
Session登陸驗證
from functools import wrapsdef check_login(func):@wraps(func)def inner(request, *args, **kwargs):next_url = request.get_full_path()if request.session.get("user"):return func(request, *args, **kwargs)else:return redirect("/login/?next={}".format(next_url))return innerdef login(request):if request.method == "POST":user = request.POST.get("user")pwd = request.POST.get("pwd")if user == "alex" and pwd == "alex1234":# 設置sessionrequest.session["user"] = user# 獲取跳到登陸頁面之前的URLnext_url = request.GET.get("next")# 如果有,就跳轉回登陸之前的URLif next_url:return redirect(next_url)# 否則默認跳轉到index頁面else:return redirect("/index/")return render(request, "login.html")@check_login
def logout(request):# 刪除所有當前請求相關的sessionrequest.session.delete()return redirect("/login/")@check_login
def index(request):current_user = request.session.get("user", None)return render(request, "index.html", {"user": current_user})
補充:
有時一些數據可以存入session,django_session表中。
eg:驗證碼
?
?
參考:https://www.cnblogs.com/guyouyin123/p/12297103.html
?