天天看點

day56 cookie和session和中間件day56 cookie和session和中間件

day56 cookie和session和中間件

Cookie和session

Cookie初識

Cookie的由來

大家都知道HTTP協定是無狀态的。

無狀态的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關系,它不會受前面的請求響應情況直接影響,也不會直接影響後面的請求響應情況。

一句有意思的話來描述就是人生隻如初見,對伺服器來說,每次的請求都是全新的。

狀态可以了解為用戶端和伺服器在某次會話中産生的資料,那無狀态的就以為這些資料不會被保留。會話中産生的資料又是我們需要儲存的,也就是說要“保持狀态”。是以Cookie就是在這樣一個場景下誕生。

并且還有一個問題就是,你登陸我的網站的時候,我沒法确定你是不是登陸了,之前我們學的django,雖然寫了很多頁面,但是使用者不用登陸都是可以看所有網頁的,隻要他知道網址就行,但是我們為了自己的安全機制,我們是不是要做驗證啊,通路哪一個網址,都要驗證使用者的身份,但是還有保證什麼呢,使用者登陸過之後,還要保證登陸了的使用者不需要再重複登陸,就能夠通路我網站的其他的網址的頁面,對不對,但是http無狀态啊,怎麼保證這個事情呢?此時就要找cookie了。

什麼是Cookie

首先來講,cookie是浏覽器的技術,Cookie具體指的是一段小資訊,它是伺服器發送出來存儲在浏覽器上的一組組鍵值對,可以了解為服務端給用戶端的一個小甜點,下次通路伺服器時浏覽器會自動攜帶這些鍵值對,以便伺服器提取有用資訊。

Cookie的原理

Cookie的工作原理是:浏覽器通路服務端,帶着一個空的cookie,然後由伺服器産生内容,浏覽器收到相應後儲存在本地;當浏覽器再次通路時,浏覽器會自動帶上Cookie,這樣伺服器就能通過Cookie的内容來判斷這個是“誰”了。

Http協定特點

  • 無狀态,無連接配接(HTTP 1.1 版本出現了短連接配接)
  • 格式:請求行 – 請求頭 – 空行 – 請求資料

django 操作cookie

擷取cookie:

擷取簽名cookie(不常用):

設定cookie:

設定簽名cookie(不常用):

設定cookie逾時時間和過期日期:

ret.set_cookie('is_login',True,max_age=5) # 逾時時間 秒數
ret.set_cookie('is_login',True,expires=datetime.datetime.now() + datetime.timedelta(days=7))  #過期日期
           

删除cookie:

session的優勢

  1. 借助于cookie進行傳輸
  2. 非明文顯示
  3. 長度不限
  4. Django為我們提供了十分友善的session使用接口,隻需要簡單地幾條指令就可以實作session的設定、擷取和清空。

設定session

設定session的指令包括三個步驟:

  1. 生成随機字元串
  2. 放到cookie中進行傳輸
  3. 将随機字元串和對應資料儲存到自己服務端的資料庫中,django-session表

擷取session

這簡簡單單的一條指令,其實隐含了大約三個擷取session的步驟,也就是設定session的逆過程:

# 1 取出cookie中的session随機字元串{'sessionid':'asdfasfpoaijsdgihsdj'}
xx = request.COOKIES.get('sessionid')
# 2 到資料庫中查詢這個sessionid對應的那條記錄
data = select session_data from django_session where session_key = xx;
# 3 拿出記錄中的session_data資料部分進行解密,并取出資料
dic = sss(data) -- {'is_login':True}
dic.get('is_login') -- True
	
           

登出session

@func
def logout(request):
    request.session.flush()  # 删除session
        return redirect('login')
           

session.flush()

指令是将session登出,主要是兩個步驟:

  1. 删除cookie中的sessionid那個鍵值對
  2. 删除了資料庫中的這條記錄

Cookie 和 session 的總結與對比

cookie:

  • 保持會話,使使用者不需要重複地去登入
  • 有大小限制
  • 有個數限制
  • Cookie總大小上限為4KB
  • 一個伺服器最多在用戶端浏覽器上儲存20個Cookie
  • 一個浏覽器最多儲存300個Cookie,因為一個浏覽器可以通路多個伺服器

session:

  • 比cookie面上安全一些
  • session沒有大小限制
  • 可以配置多個存儲方案,可以配置到緩存中

中間件

自定義中間件

# 第一步,在應用下面建立一個檔案夾,名字随便,比如mymiddleware,在這個檔案夾下建立 一個py檔案,名字随便,比如叫做xx.py

# 第二步:在xx.py檔案中定義類,寫法如下
	
    from django.shortcuts import redirect,HttpResponse,render
    from django.utils.deprecation import MiddlewareMixin  #引入django這個類

    class Auth(MiddlewareMixin):  #繼承這個類
        # 白名單  認證白名單
        white_list = ['/login/',]

        def process_request(self,request):  #想對請求進行統一的處理,那麼就定義一個process_request方法
        	# 如果方法傳回值是None,那就通過了這個方法的認證或者處理,如果傳回的值HttpResponse對象,那麼請求到這裡就結束了,直接傳回給了浏覽器
            if request.path in self.white_list:
                pass
            else:
                is_login = request.session.get('is_login')
                if is_login == True:
                    pass
                else:
                    return HttpResponse('滾犢子!!')

# 第三步,settings配置檔案中寫上這個類的路徑
	
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

    'app01.mymiddleware.xx.Auth',
]
           

process_response方法

def process_response(self,request,response):
    '''

        :param request:
        :param response:  就是視圖的傳回值(HttpResponse對象)
        :return:
        '''
    # print(response)
    return response
           

process_view以及執行順序

from django.shortcuts import redirect,HttpResponse,render

# 引入django的子產品
from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self,request):

        print('MD1--process_request')

        return HttpResponse('xxxlpapsjdfoajsdfh')

    def process_response(self, request,response):
        print('MD1--process_response')
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print('MD1---',view_func.__name__)
		# view_func就是url對應那個views裡面的視圖函數,視圖函數的參數view_args, view_kwargs

class MD2(MiddlewareMixin):

    def process_request(self, request):
        print('MD2--process_request')

    def process_response(self, request, response):
        print('MD2--process_response')
        return response
    def process_view(self, request, view_func, view_args, view_kwargs):
        print('MD2---',view_func.__name__)