1. 程式人生 > 其它 >React元件複用的發展史

React元件複用的發展史

目錄

Cookie與Session

HTTP被設計為”⽆態”,也就是俗稱“臉盲”。 這⼀次請求和下⼀次請求 之間沒有任何狀態保持,我們⽆法根據請求的任何⽅⾯(IP地址,⽤戶代理等)來識別來自同⼀ 個⼈的連續請求。

實現狀態保持的⽅式:在客戶端或伺服器端儲存與會話有關的資料 (客戶端與伺服器端的⼀次通訊,就是⼀次會話)

  • cookie
  • session

不同的請求者之間不會共享這些資料,cookie和session與請求者⼀⼀對應

"""
發展史:
	1.網站沒有儲存使用者功能的需求,所有使用者訪問返回的結果都是一樣的	eg:新聞,部落格,文章
	
	2.出現了一些需要儲存使用者資訊的網站
		eg:淘寶,支付寶,京東.....
		
	以登入功能為例子,如果不儲存使用者登陸狀態,也就意味著使用者每次訪問網站都需要重複的輸入使用者名稱和密碼(這樣的網站你還想用嗎?)
	當用戶第一次登入成功之後,將使用者的密碼返回給使用者瀏覽器,讓使用者瀏覽器儲存在本地,之後訪問網站的時候瀏覽器會自動將儲存在瀏覽器上的使用者名稱和密碼傳送給服務端,服務端獲取之後,自動校驗。
	早期這種方式具有很大的安全隱患,
	
	
	優化:
		當用戶登入成功之後,服務端產生一個隨機字串(在服務端儲存資料,用Kv鍵值對的形式),交由客戶端瀏覽器儲存,
		
		隨機字串1:使用者1的相關資訊
		隨機字串2:使用者2的相關資訊
		隨機字串3:使用者3的相關資訊
		
		之後訪問服務端的時候,都帶著該隨機字串,服務端去資料庫中比對是否有對應的隨機字串,從而獲取到對應的使用者資訊
		
但是如果拿到了隨機字串,那麼就可以冒充當前使用者,其實還存在安全隱患


在web領域,沒有絕對的安全,也沒有絕對的不安全
		
			
"""
cookie 	
	服務端儲存在客戶端瀏覽器上的資訊都可以稱之為cookie
    它的表現形式一般都是k:v鍵值對(可以有多個)
session
	資料是儲存在服務端的,並且它的表現形式一般都是k:v鍵值對(可以有多個)
token
	session雖然資料儲存在服務端,但是禁不住資料量大
    服務端不再儲存資料,而是在登入成功之後,將一段資訊進行加密處理,(加密演算法只有自己知道),將加密後的結果拼接在資訊後面,整體返回給瀏覽器儲存,瀏覽器下次再訪問的時候帶著該資訊,服務端自動切取前面一段資訊,再次使用自己的加密演算法跟瀏覽器尾部的密文進行比對

jwt認證
	
 
"""總結"""
	1.cookie是儲存在客戶端瀏覽器上的資訊
    2.session就是儲存在服務端上的資訊
    3.session是基於cookie工作的(大部分的儲存使用者狀態的操作都需要使用到cookie)

1、Django操作cookie

#雖然cookie是服務端告訴客戶端需要儲存的內容
#但是客戶端可以選擇拒絕儲存,禁止了之後只要是需要記錄使用者狀態的網站登入功能都無法使用
# 檢視函式的返回值
return HttpResponse()
return render()
return redirects()

#如果想要操作cookie,就必須利用obj物件,不能再像之前那樣寫檢視函式的返回值了
obj1=HttsResponse()
return obj1
obj2=render()
return obj2
obj3=redirect()
return obj3


"""設定cookie"""
	obj.set_cookie(key,value='')
"""獲取cookie"""
	request.COOKIES.get(key)
    request.get_signed_cookie(key, default=RAISE_ERROR, salt='鹽', max_age=None)
"""設定超時時間"""
	在設定cookie的時候,可以新增超時時間
    obj.set_cookie('username', 'zs666', max_age=5, expires=3)
    
    max_age
    expires
    	兩者都是設定超時時間,都是以秒為單位,
        需要注意的是針對IE瀏覽器需要使用expires
"""刪除cookie"""
obj.delete_cookie('username')

"""加鹽"""
obj.set_sifned_cookie(key,value,salt='鹽')

簡單實現使用者登入

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'zhao' and password == '123':
            # 儲存使用者登入狀態
            obj = redirect('home')
            # 讓瀏覽器記錄cookie資料
            obj.set_cookie('username', 'zs666')
            """
            瀏覽器不單單會幫你存,而且每次訪問的時候都會帶著它
            """
            # 跳轉到一個需要使用者登入才能看到的頁面
            return obj
    return render(request, 'login.html')


def home(request):
    # 獲取cookie資訊,進行判斷
    if request.COOKIES.get('username') == 'zs666':
        return HttpResponse('我是Home頁面,只有登入的使用者才可進來')
    # 沒有登入應該跳轉到登入頁面
    return redirect('login')

加入裝飾器

"""
使用者如果再沒有登入的情況下,想訪問一個需要登入的頁面,那麼先跳轉到登入頁面,
當用戶輸入正確的使用者名稱和密碼之後,
應該跳轉到使用者之前想到訪問的頁面,而不是直接寫死
"""


# 校驗使用者是否登入的裝飾器
def login_auth(func):
    def inner(request, *args, **kwargs):
        target_url = request.get_full_path()
        if request.COOKIES.get('username'):
            res = func(request, *args, **kwargs)
            return res
        else:
            return redirect('/login/?next=%s' % target_url)

    return inner


def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'zhao' and password == '123':
            # 獲取使用者上一次想要訪問的url
            target_url = request.GET.get('next')
            if target_url:
                obj = redirect(target_url)
            else:
                # 儲存使用者登入狀態
                obj = redirect('home')
                # 讓瀏覽器記錄cookie資料
            obj.set_cookie('username', 'zs666')
            """
            瀏覽器不單單會幫你存,而且每次訪問的時候都會帶著它
            """
            # 跳轉到一個需要使用者登入才能看到的頁面
            return obj
    return render(request, 'login.html')


@login_auth
def home(request):
    # 獲取cookie資訊,進行判斷
    # if request.COOKIES.get('username') == 'zs666':
    #     return HttpResponse('我是Home頁面,只有登入的使用者才可進來')
    # 沒有登入應該跳轉到登入頁面
    # return redirect('login')
    return HttpResponse('我是Home頁面,只有登入的使用者才可進來')


@login_auth
def index(request):
    # return redirect('login')
    return HttpResponse('我是index頁面,只有登入的使用者才可進來')


@login_auth
def func(request):
    return HttpResponse('我是func頁面,只有登入的使用者才可進來')


# 登出,刪除cookie
@login_auth
def logout(request):
    obj = redirect('login')
    obj.delete_cookie('username')
    return obj

2、Django操作session

session資料儲存在服務端,給客戶端返回的是一個隨機字串
	sessionid:隨機字串	
1.預設情況下操作session的時候需要Django預設的一張django_session表
	資料庫遷移命令
    	django會自動的建立多張表,django_session就是其中的一張
"""設定session"""
request.session['key'] = value
"""獲取session"""
request.session.get('key')
"""設定過期時間"""
request.session.set_expiry()
	括號內可以放四種類型的引數
    	1.整數   				多少秒
        2.日期物件   			到指定日期就失效
        3. 0 				  一旦當前瀏覽器視窗關閉立刻失效
        4. 不寫				失效時間取決於django內部全域性session預設的的失效時間(14天)
"""清除session"""
	request.session.delete() #只刪服務端的session,客戶端的不刪
	request.session.flush() #瀏覽器和服務端都清空
 


2.session是儲存在服務端的,但是session的儲存位置可以有多種選擇
	1.MySQL
    2.檔案
    3.redis
    4.memcache
    ......
	
    
django_session表中的資料條數,是取決於瀏覽器的
	同一個計算機上(IP地址),同一個瀏覽器只會同時有一條資料生效
    (當session過期的時候,可能會出現多條資料對應一個瀏覽器,但是該現象不會持續很久,內部會自動識別過期的資料清除,也可以手動通過程式碼清除)
    主要是為了節省服務端資料庫資源
    

先執行資料庫遷移的兩條命令,檢視django_session表結構

如果沒有先執行資料庫遷移命令,那麼會報(no such table:django_session)錯誤

設定session

def set_session(request):
    # 設定session
    request.session['hobby'] = 'JayChou'
    """
    設定session內部發生了那些事?
        1.django內部會自動生成一個隨機字串
        2.django內部自動將隨機字串和後面對應的資料儲存到django_session表中(這一步不是直接生效的,)
            2.1先在記憶體中產生操作資料的快取
            2.2在響應結果django中介軟體的時候才真正的操作資料
        3.將產生的隨機字串返回給客戶端瀏覽器儲存
    """

    return HttpResponse('稻香')

然後在瀏覽器輸入路由,回車後,django_session表中會自動生成資料,

expire_data欄位是過期時間


session給客戶端返回的是一個隨機字串,隨機字串指的就是django_session表中的session_key

django預設的session過期時間是14,但是也可以修改

獲取session

def get_session(request):
    # 獲取session
    print(request.session.get('hobby'))
    """
    獲取session發生了那些事:
        1.自動從瀏覽器請求中獲取sessionid對應的隨機字串
        2.拿著該隨機字串去django_session表中查詢對應的資料,
        3.如果比對上了,則將對應的資料取出並以字典的形式封裝到request.session中
            比對不上,則request.session.get()返回None
    """
    return HttpResponse('haha')

過期時間

request.session.set_expiry()
	括號內可以放四種類型的引數
    	1.整數   				多少秒
        2.日期物件   			到指定日期就失效
        3. 0 				  一旦當前瀏覽器視窗關閉立刻失效
        4. 不寫				失效時間取決於django內部全域性
def set_session(request):
    # 設定session
    request.session['hobby'] = 'JayChou'
    # 設定超時時間
    request.session.set_expiry(0) # 瀏覽器關閉就失效
    return HttpResponse('稻香')

def get_session(request):
    # 獲取session
    # print(request.session.get('hobby'))
    if request.session.get('hobby'):
        print(request.session.get('hobby'))
        return HttpResponse('haha')
    return HttpResponse('瀏覽器視窗關閉過了,得不到session資料')

清除session

def del_session(request):
    request.session.delete() ##只刪服務端的session,客戶端的不刪
    return HttpResponse("刪除")



推薦使用request.session.flush() #瀏覽器和服務端都清空