首頁 > 軟體

day55:django:cookie&session

2020-09-22 19:30:07

目錄

1.Cookie

  1.Cookie前戲

  2.Cookie的引入

  3.django中操作cookie

2.Session

  1.cookie的侷限性

  2.session技術

  3.django操作session

  4.Session詳細流程解析

  5.session例項分析

  6.對於cookie和session的總結

3.django外部指令碼呼叫django環境

Cookie

1.Cookie前戲

HTTP協議的兩個特點

1.無連線

將協議設計為請求時建連線、請求完釋放連線,以儘快將資源釋放出來服務其他客戶端。

2.無狀態

什麼是無狀態?

無狀態的意思是每次請求都是獨立的

它的執行情況和結果與前面的請求和之後的請求都無直接關係,

它不會受前面的請求響應情況直接影響,

也不會直接影響後面的請求響應情況

簡單的來說:無狀態是指伺服器不知道客戶端是什麼狀態

對於無狀態的解釋

要明白,這句話的含義是指在說明,http協議作為技術背景的web應用程式請求——應答模式是無狀態的,這個事實基本不會發生改變,也不會因為加入cookies、session機制而變成有狀態的。

要明白,這種前後因果關係:“我們要實現的是一種web應用,實現這種應用的協議我們選擇了http這種本質上是無狀態的通訊協議

但是事實上,我們需要我們的web應用是有狀態的。所以我們加入了cookies、session等機制去實現有狀態的web應用。

2.Cookie的引入

1.cookie的引入

因為http無狀態,所以出現了cookie,cookie是一種瀏覽器技術

2.cookie能做什麼?

1.瀏覽器訪問服務端,帶著一個的cookie,

2.然後由伺服器產生內容瀏覽器收到相應後儲存在本地

3.當瀏覽器再次訪問時,瀏覽器會自動帶上Cookie,這樣伺服器就能通過Cookie的內容來判斷這個是“誰”了。

3.cookie規範

  •  Cookie大小上限為4KB; 
  •  一個伺服器最多在客戶端瀏覽器上儲存20個Cookie; 
  •  一個瀏覽器最多儲存300個Cookie,因為一個瀏覽器可以訪問多個伺服器。

    上面的資料只是HTTP的Cookie規範,但在瀏覽器大戰的今天,一些瀏覽器為了打敗對手,為了展現自己的能力起見,可能對Cookie規範“擴展”了一些,例如每個Cookie的大小為8KB,最多可儲存500個Cookie等!但也不會出現把你硬碟佔滿的可能! 
注意,不同瀏覽器之間是不共用Cookie的。也就是說在你使用IE訪問伺服器時,伺服器會把Cookie發給IE,然後由IE儲存起來,當你在使用FireFox訪問伺服器時,不可能把IE儲存的Cookie傳送給伺服器。

4.cookie和HTTP頭

 Cookie是通過HTTP請求和響應頭在客戶端和伺服器端傳遞的: 

  • Cookie:請求頭,客戶端傳送給伺服器端; 
  • 格式:Cookie: a=A; b=B; c=C。即多個Cookie用分號離開; 
  • Set-Cookie:響應頭,伺服器端傳送給客戶端; 
  • 格式:一個Cookie物件一個Set-Cookie: Set-Cookie: a=A Set-Cookie: b=B Set-Cookie: c=C  

5.cookie的覆蓋

如果伺服器端傳送重複的Cookie那麼會覆蓋原有的Cookie,例如客戶端的第一個請求伺服器端傳送的Cookie是:Set-Cookie: a=A;第二請求伺服器端傳送的是:Set-Cookie: a=AA,那麼客戶端只留下一個Cookie,即:a=AA。 

3.django中操作cookie

cookie的獲取/設定/修改/刪除

1.獲取cookie

# 獲取cookie
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) #帶簽名的值
'''
參數:
default: 預設值
salt: 加密鹽
max_age: 後臺控制過期時間
'''

2.設定cookie

# 設定cookie
'''cookie的獲取都是基於request物件的'''
'''cookie的設定都是基於HttpResponse物件的'''
rep = HttpResponse(...)
rep = render(request, ...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密鹽', max_age=None, ...)

3.修改cookie

# 修改cookie
ret.set_cookie('username', 'xxx')  #相同的鍵設定不同的值就是修改

4.刪除cookie

# 刪除cookie
ret.delete_cookie('username')

cookie參數的意義

key #
value='' #
max_age=None # 超時時間,單位為秒  5表示5秒後失效
expires=None # 超時時間(IE requires expires,so set it if hasn't been already.)值為時間日期類型資料
path='/' # Cookie生效的路徑,/ 表示根路徑,特殊的:根路徑的cookie可以被任何url的頁面訪問
domain=None # Cookie生效的域名
secure=True #  https傳輸
httponly=False # 只能http協議傳輸,無法被JavaScript獲取(不是絕對,底層抓包可以獲取到也可以被覆蓋)

Session

1.cookie的侷限性

1.cookie是明文儲存

2.cookie的大小限制

  Cookie大小上限為4KB;

  一個伺服器最多在客戶端瀏覽器上儲存20個Cookie;

  一個瀏覽器最多儲存300個Cookie,因為一個瀏覽器可以訪問多個伺服器。

2.session技術

session比cookie的強大之處

Cookie雖然在一定程度上解決了“保持狀態”的需求,但是由於Cookie本身最大支援4096位元組,以及Cookie本身儲存在客戶端,可能被攔截或竊取,

因此就需要有一種新的東西,它能支援更多的位元組,並且他儲存在伺服器,有較高的安全性。這就是Session

cookie的橋接作用

問題來了,基於HTTP協議的無狀態特徵,伺服器根本就不知道訪問者是“誰”。那麼上述的Cookie就起到橋接的作用。

我們可以給每個客戶端的Cookie分配一個唯一的id,這樣使用者在訪問時,通過Cookie,伺服器就知道來的人是“誰”。

然後我們再根據不同的Cookie的id,在伺服器上儲存一段時間的私密資料,如“賬號密碼”等等。

cookie和session各自實現的功能總結

總結而言:Cookie彌補了HTTP無狀態的不足,讓伺服器知道來的人是“誰”;

       但是Cookie以文字的形式儲存在本地,自身安全性較差;

     所以我們就通過Cookie識別不同的使用者,對應的在Session裡儲存私密的資訊以及超過4096位元組的文字。

3.django操作session

# 設定session
request.session['k1'] = 123
request.session.setdefault('k1',123)

# 獲取session
request.session['k1'] 
request.session.get('k1',None)

# 刪除session
del request.session['k1']

# 清空session
request.session.flush()

4.Session詳細流程解析

5.session例項分析

這是一段登入的檢視函數,在函數中新增兩個session,在新增session時,做了三件事

def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    else:
        uname = request.POST.get('username')
        if uname == 'root' or uname=='abc':
            request.session['is_login'] = True
            request.session['username'] = uname
            # request.session
            # 1 生成一個隨機字元串
            # 2 將隨機字元串放到cookie中,名稱為sessionid
            # 3 將設定的session資料,序列化+加密,儲存到了django-session表中
            return redirect('/home/')
        else:
            return redirect('/login/')

這是一段登出的檢視函數,這個時候我們要刪除session,在刪除session時,做了兩件事

def logout(requset):
    requset.session.flush()
    # 1 刪除cookie中的資料
    # 2 刪除資料庫中django-session表中的記錄
    return redirect('/login/')

這是一個基於session的登入認證中介軟體,這個時候我們要修改session,在修改session,做了三件事

# 基於session的登入認證中介軟體
class LoginAuth(MiddlewareMixin):
    white_list = ['/login/', ]  # 白名單
    def process_request(self,request): 
        path = request.path # 獲取當前請求路徑
        if path not in self.white_list: # 如果路徑不在白名單內
            is_login = request.session.get('is_login') # 獲取session中is_login的值
            # request.session['is_login']
            # 1 取出請求中cookie鍵為sessionid的值
            # 2 通過這個值到django-session表中獲取資料
            # 3 將資料解密並且反序列化得到原來的資料
            if is_login != True:
                return redirect('/login/')

6.對於cookie和session的總結

...

django外部指令碼呼叫django環境

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_cookie.settings")
import django
django.setup()

from app01 import  models
models.Book.objects.create(
    title='xxx',
    price=200,
)

IT145.com E-mail:sddin#qq.com