日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Django框架之會話技術(shù)之Cookie與Session

會話(Session)跟蹤是Web程序中常用的技術(shù),用來跟蹤用戶的整個會話。常用的會話跟蹤技術(shù)是Cookie與Session。Cookie通過在客戶端記錄信息確定用戶身份,Session通過在服務(wù)器端記錄信息確定用戶身份。

專注于為中小企業(yè)提供成都網(wǎng)站設(shè)計、做網(wǎng)站服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)海城免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了數(shù)千家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。

會話跟蹤技術(shù)

什么是會話跟蹤技術(shù)

我們可以把會話理解為客戶端與服務(wù)器之間的一次會晤,在一次會晤中可能會包含多次請求和響應(yīng)。

例如,我們給10086打電話,我就是客戶端,而10086服務(wù)人員就是服務(wù)端。從雙方接通電話那一刻起,會話就開始了,到某一方掛斷電話標(biāo)識會話結(jié)束。在通話過程中,我們會向10086發(fā)出多個請求,那么多個請求都在一個會話中。

在Web中,客戶使用瀏覽器向某一服務(wù)器發(fā)出第一個請求開始,會話就開始了,直到客戶關(guān)閉了瀏覽器會話結(jié)束。

在一個會話的多個請求中共享數(shù)據(jù),這就是會話跟蹤技術(shù)。

例如,在一個會話中的請求如下:請求銀行主頁。

1)請求登錄(請求參數(shù)是用戶名和密碼);

2)請求轉(zhuǎn)賬(請求參數(shù)與轉(zhuǎn)賬相關(guān)的數(shù)據(jù));

3)請求信用卡還款(請求參數(shù)與還款相關(guān)的數(shù)據(jù))。

在上面會話中,當(dāng)前用戶信息必須在這個會話中共享的,因為登錄的是張三,那么在轉(zhuǎn)賬和還款時一定是張三的轉(zhuǎn)賬和還款,這就說明我們必須在一個會話過程中共享數(shù)據(jù)的能力。

會話路徑技術(shù)使用Cookie或session完成

在Web應(yīng)用中,HTTP協(xié)議是無狀態(tài)的,即每次請求都是獨立的,無法記錄前一次請求的狀態(tài),每次請求都是一次新的請求。

無狀態(tài)原因:瀏覽器與服務(wù)器是使用Socket套接字進行通信的,服務(wù)器將請求結(jié)果返回給瀏覽器之后,會關(guān)閉當(dāng)前的Socket連接,而且服務(wù)器也會在處理頁面完畢之后銷毀頁面對象。

但是,有時候我們需要知道上次請求狀態(tài),比如用戶是否登錄過,瀏覽過哪些商品等??梢允褂脮捀?,可以使用Cookie、Session、token(自定義的session)。

Cookie

什么叫做Cookie

Cookie,翻譯成中文小甜點,小餅干的意思。在HTTP中它表示服務(wù)器送給客戶端瀏覽器的小甜點。

Cookie是客戶端會話技術(shù),數(shù)據(jù)都存儲在客戶端,以key-value進行存儲。支持過期時間max_age,默認(rèn)請求會攜帶本網(wǎng)站的所有cookie,cookie不能跨域名,不能跨瀏覽器,cookie默認(rèn)不支持中文,base64。

Cookie是由服務(wù)器創(chuàng)建,通過服務(wù)端的響應(yīng)發(fā)送給客戶端瀏覽器的一個鍵值對,然后瀏覽器會把Cookie保存起來,并標(biāo)注出Cookie的來源(哪個服務(wù)器的Cookie),當(dāng)客戶端下一次再訪問服務(wù)器時,默認(rèn)請求會攜帶本這個服務(wù)器的所有Cookie,這樣服務(wù)器就可以識別客戶端了。

設(shè)置cookie應(yīng)該是服務(wù)器response,獲取cookie應(yīng)該在瀏覽器request,刪除cookie應(yīng)該在服務(wù)器response。

Cookie規(guī)范

  • Cookie大小上限為4KB;
  • 一個服務(wù)器最多在客戶端瀏覽器上保存20個Cookie;
  • 一個瀏覽器最多保存300個Cookie;

上面的數(shù)據(jù)只是HTTP的Cookie規(guī)范,但是,在瀏覽器百家爭鳴的當(dāng)下,一些瀏覽器為了爭奪一份份額,展現(xiàn)自己的優(yōu)勢,可能對Cookie的規(guī)范擴展,例如每個Cookie的大小為8KB,最多可保存500個Cookie等!但也不會出現(xiàn)把你硬盤占滿的可能!

注意,不同瀏覽器之間是不共享Cookie的。也就是說在你使用IE訪問服務(wù)器時,服務(wù)器會把Cookie發(fā)給IE,然后由IE保存起來,當(dāng)你在使用FireFox訪問服務(wù)器時,不可能把IE保存的Cookie發(fā)送給服務(wù)器

Cookie與HTTP頭

Cookie是通過HTTP請求頭和響應(yīng)頭在客戶端和服務(wù)器端傳遞的:

Set-Cookie:響應(yīng)頭,服務(wù)器端發(fā)送給客戶端;

Cookie:請求頭,客戶端發(fā)送給服務(wù)器端;格式:Cookie: a=A; b=B; c=C。即多個Cookie用分號隔開;

一個Cookie對象一個Set-Cookie:Set-Cookie: a=A Set-Cookie: b=B Set-Cookie: c=C;

Cookie的覆蓋

如果服務(wù)器端發(fā)送重復(fù)的Cookie那么會覆蓋原有的Cookie,例如客戶端的第一個請求服務(wù)器端發(fā)送的Cookie是:Set-Cookie: a=A;第二請求服務(wù)器端發(fā)送的是:Set-Cookie: a=AA,那么客戶端只留下一個Cookie,即:a=AA。

請求流程

第一次請求:

① 瀏覽器第一次請求服務(wù)器的時候,不會攜帶任何cookie信息,,請求頭中沒有任何cookie信息;

② 當(dāng)服務(wù)器接受到這個請求之后,會做一些驗證,例如進行用戶名和密碼的驗證,驗證沒有問題則可以設(shè)置cookie信息。

③ 服務(wù)器會為響應(yīng)設(shè)置cookie信息,響應(yīng)頭中有set_cookie信息。

③ 我們的瀏覽器接收到這個響應(yīng)之后,發(fā)現(xiàn)響應(yīng)中有cookie信息,瀏覽器會將cookie信息保存起來。

后續(xù)請求:① 第二次或之后的請求都會攜帶cookie信息,請求頭中有cookie信息;

② 服務(wù)器接受到請求之后,會發(fā)現(xiàn)請求中攜帶cookie信息,這樣就認(rèn)識是誰的請求了。

代碼實現(xiàn)

login.html文件:

 
 
 
 
  1.     
  2.     登錄界面
  3.     
  4.     
  5.         

    登錄界面

  6.         
  7.             {% csrf_token %}
  8.             帳 號:
  9.             
  10.             密 碼:
  11.             
  12.             
  13.               
  14.             
  15.         
  16.     
  • home.html文件:

     
     
     
     
    1.     
    2.     首頁
    3.     歡迎
    4.     {% if username %}
    5.         {{ username }}
    6.     {% else %}
    7.         游客
    8.     {% endif %}
    9.     訪問~~
    10.     
    11.     退出

    views.py:

     
     
     
     
    1. def login(request):
    2.     if request.method == 'GET':
    3.         return render(request, 'login.html')
    4.     elif request.method == 'POST':
    5.         username = request.POST.get('username')
    6.         password = request.POST.get('password')
    7.         if username and password:   # 此處為了方便測試,沒有去數(shù)據(jù)庫進行校驗,實際的需要去數(shù)據(jù)庫校驗用戶名和密碼之類的
    8.             '''
    9.                 響應(yīng)體:
    10.                 return HttpResponse()
    11.                 return render()
    12.                 return redirect()    
    13.                都可以           
    14.             
    15.             '''
    16.             response = redirect(reverse('user:home'))
    17.             # 設(shè)置cookie信息
    18.             response.set_cookie('username', username)
    19.             is_login = True
    20.             response.set_cookie('is_login', is_login)
    21.             return response
    22.         return render(request, 'login.html')
    23. def home(request):
    24.     # 獲取cookie信息
    25.     is_login = request.COOKIES.get('is_login')
    26.     username = request.COOKIES.get('username')
    27.     if is_login:
    28.         return render(request, 'home.html', {'username': username})
    29.     return redirect(reverse('user:login'))
    30. def logout(request):
    31.     response = redirect(reverse('user:login'))
    32.     # 刪除cookie信息
    33.     response.delete_cookie('is_login')
    34.     response.delete_cookie('username')  # 注銷,最好都刪除,避免注冊之后下次還會攜帶未刪除的信息
    35.     return response

    我們可以看到第一次打開登錄頁面的時候,不攜帶Cookie信息(csrf暫忽略):

    我們再登錄,即提交表單之后,服務(wù)器設(shè)置了Cookie(可參考上面設(shè)置Cookie信息代碼):

    退出,即刪除Cookie信息,這里只刪除is_login的信息

    上面是以明文的方式顯示,我們可以進行加鹽設(shè)置,以加密形式顯示:

     
     
     
     
    1. def login(request):
    2.     if request.method == 'GET':
    3.         return render(request, 'login.html')
    4.     elif request.method == 'POST':
    5.         username = request.POST.get('username')
    6.         response = redirect(reverse('user:home'))
    7.         #response.set_cookie('username', username)
    8.         #set_signed_cookie(key,value,salt='加密鹽',...) 
    9.         response.set_signed_cookie('username', username, 'qmpython')
    10.         return response
    11. def home(request):
    12.     username = request.COOKIES.get('username')
    13.     # 解密
    14.     #username = request.get_signed_cookie('username', 'qmpython')    
    15.     response = HttpResponse(f'{username}登錄成功')
    16.     return response

    Cookie:具體一個瀏覽器針對一個服務(wù)器存儲key-value。

    注意,不同瀏覽器之間是不共享Cookie的。也就是說在你使用IE訪問服務(wù)器時,服務(wù)器會把Cookie發(fā)給IE,然后由IE保存起來,當(dāng)你在使用Chrome訪問服務(wù)器時,不可能把IE保存的Cookie發(fā)送給服務(wù)器。

    同一個瀏覽器訪問A網(wǎng)站,又去訪問B網(wǎng)站,不可能將A的cookie信息攜帶發(fā)送給B服務(wù)器。

    默認(rèn)情況下,Cookie只在瀏覽器的內(nèi)存中存活,也就是說,當(dāng)你關(guān)閉瀏覽器后,Cookie就會消失!

    問題一:如果只是關(guān)閉網(wǎng)站(關(guān)閉標(biāo)簽頁),沒有退出瀏覽器呢?

    A:并不會,如果在不關(guān)閉瀏覽器,只關(guān)閉頁面時,清除cookie??梢允褂胘s事件處理:

     
     
     
     

    set_cookie參數(shù):

     
     
     
     
    1. class HttpResponseBase:
    2.     def set_cookie(self, 
    3.                    key,  # 鍵
    4.                    value='', # 值
    5.                    max_age=None, # cookie有效時長,單位為秒,默認(rèn)為None表示關(guān)閉瀏覽器失效,指定          為有效數(shù)值100表示100秒后自動失效
    6.                    
    7.                    expires=None, # 支持一個datetime或timedelta,可以指定一個具體的日期,           expires=timedelta(days=10)表示十天后過期。
    8.                    # max-age和exepires兩個指定一個。
    9.                    
    10.                    path='/',  # Cookie生效的路徑,瀏覽器只會把cookie回傳給帶有該路徑的頁面,這樣可以避免將;cookie傳給站點中的其他的應(yīng)用。;/ 表示根路徑,特殊的:根路徑的cookie可以被任何url的頁面訪問
    11.                    
    12.                    domain=None,  ''' Cookie生效的域名;你可用這個參數(shù)來構(gòu)造一個跨站cookie。
    13.                      如, domain=".cdxwcx.com"
    14.                      所構(gòu)造的cookie對下面這些站點都是可讀的:
    15.                      www.cdxwcx.com 、 www2.cdxwcx.com 
    16.                 和an.other.sub.domain.cdxwcx.com 。
    17.                      如果該參數(shù)設(shè)置為 None ,cookie只能由設(shè)置它的站點讀取。
    18.                    '''
    19.                    
    20.                    secure=False,  # 如果設(shè)置為True,瀏覽器將通過HTTPS來回傳cookie
    21.                    httponly=False, # 只能http協(xié)議傳輸,無法被js獲?。ú皇墙^對的,底層抓包可以獲取到也可以被覆蓋)
    22.                    samesite=None
    23.                   ):pass

    練習(xí):使用cookie實現(xiàn)上次登錄時間

     
     
     
     
    1. def home(request):
    2.     # 獲取cookie信息
    3.     username = request.COOKIES.get('username')
    4.     last_login_time = request.COOKIES.get('last_login_time', '')
    5.     response = render(request, 'home.html', {'username': username, 'last_login_time': last_login_time})
    6.     from datetime import datetime
    7.     now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    8.     response.set_cookie('last_login_time', now)
    9.     return response

    Session

    前面介紹了Cookie,為什么還需要Session呢?其實很多情況下,只使用Cookie便能完成大部分需求。但是,只使用Cookie往往是不夠的,考慮用戶登錄信息或一些重要的敏感信息,用Cookie存儲的話會帶來一些問題,最明顯的是由于Cookie會把信息保存到本地,因此信息的安全性可能受到威脅。Session的出現(xiàn)很好地解決的這個問題,Session與Cookie類似。

    Session是服務(wù)器端技術(shù),利用這個技術(shù),服務(wù)器在運行時可以為每一個用戶的瀏覽器創(chuàng)建一個其獨享的session對象,由于session為用戶瀏覽器獨享,所以用戶在訪問服務(wù)器的web資源時,可以把各自的數(shù)據(jù)放在各自的session中,當(dāng)用戶再去訪問該服務(wù)器中的其他web資源時,其他WEB資源再從用戶各自session中取出數(shù)據(jù)為用戶服務(wù)。

    Session是服務(wù)端會話技術(shù),依賴于Cookie,如果在瀏覽器中**禁用cookie**的話,那么session就失效了,因為它需要瀏覽器的cookie值去session里做對比。

    1. 啟用Session

    Django默認(rèn)啟用Session,可以在設(shè)置文件settings.py:

     
     
     
     
    1. MIDDLEWARE = [
    2.     
    3.     'django.contrib.sessions.middleware.SessionMiddleware',
    4. ]

    如果禁用session,則注釋即可。

    2. 存儲方式

    在settings.py文件中,可以設(shè)置session數(shù)據(jù)的存儲方式,可以保存在數(shù)據(jù)庫、本地緩存等。

    2.1 數(shù)據(jù)庫

    默認(rèn)是存儲在數(shù)據(jù)庫中的。

     
     
     
     
    1. SESSION_ENGINE='django.contrib.sessions.backends.db'

    如果存儲在數(shù)據(jù)庫中,則需要安裝Session應(yīng)用,默認(rèn)已設(shè)置:

     
     
     
     
    1. INSTALLED_APPS = [
    2.     'django.contrib.sessions',
    3. ]

    在進行數(shù)據(jù)庫遷移的時候,Django自動幫我們生成了django_session表,有3個字段,分別為session_key,session_data,expris_date,Django中session的默認(rèn)過期時間是14天。

    遷移數(shù)據(jù)庫后,就會生成django_session表:

    3. 請求流程

    第一次請求:

    ① 我們第一次請求的時候可能會攜帶一些信息(例如用戶名/密碼),cookie中沒有任何信息。

    ② 當(dāng)服務(wù)器接受到這個請求之后,會做一些驗證,例如進行用戶名和密碼的驗證,驗證沒有問題則可以設(shè)置session信息。

    ③ 在設(shè)置session信息的同時(session信息保存在服務(wù)器端),服務(wù)器會在響應(yīng)頭中設(shè)置一個sessionid的cookie信息。

    ④ 客戶端(瀏覽器)在接收到響應(yīng)之后,會將cookie信息保存起來(保存sessionid的信息)。

    后續(xù)請求:

    ① 第二次或之后的請求都會攜帶sessionid的cookie信息

    ② 當(dāng)服務(wù)器接收到這個請求之后,獲取到sessionid信息,然后進行驗證,驗證成功,則可以獲取session信息(session信息保存在服務(wù)器端)

    4. 代碼實現(xiàn)

     
     
     
     
    1. def login(request):
    2.     if request.method == 'GET':
    3.         return render(request, 'login.html')
    4.     elif request.method == 'POST':
    5.         '''
    6.         響應(yīng)體:
    7.             return HttpResponse()
    8.             return render()
    9.             return redirect()    
    10.            都可以
    11.         '''
    12.         username = request.POST.get('username')
    13.         password = request.POST.get('password')
    14.         if username and password:  # 此處為了方便測試,沒有去數(shù)據(jù)庫進行校驗,實際的需要去數(shù)據(jù)庫校驗用戶名和密碼之類的
    15.             # 設(shè)置session信息
    16.             request.session['is_login'] = True
    17.             request.session['username'] = username
    18.             '''
    19.             以上設(shè)置,實際執(zhí)行以下操作:
    20.             1、生成隨機字符串,例如:123abc!@#
    21.             2、response.set_cookie("sessionid", 123abc!@#)
    22.             3、在django_session表中創(chuàng)建一條記錄:
    23.                 session_key         session_data
    24.                 123abc!@#           {"is_login":True, "username": "admin"}        
    25.             
    26.             '''
    27.         return redirect(reverse('user:home'))
    28.     
    29. def home(request):
    30.     is_login = request.session['is_login']
    31.     username = request.session['username']
    32.     '''
    33.     以上執(zhí)行以下操作:
    34.     1)  request.COOKIES.get('sessionid'),獲得session_key
    35.     2) 通過上面得到的session_key,在django_session表中獲取對應(yīng)的session_data
    36.     3) 從session_data獲取is_login值。    
    37.     '''
    38.     if is_login:
    39.         return render(request, 'home.html', {'username': username})
    40.     return redirect(reverse('user:login'))
    41. def logout(request):
    42.     response = redirect(reverse('user:login'))
    43.     
    44.     # 刪除session數(shù)據(jù),即刪除了session_data字段值中對應(yīng)鍵和值,但是cookie信息還存在,請求還會攜帶cookie信息,也就成了臟數(shù)據(jù),通過cookie再找session,已經(jīng)找不到了。
    45.     #del request.session['is_login'] 
    46.     
    47.     # 清除所有session,禁用!?。?/li>
    48.     request.session.clear()     
    49.     # 清除當(dāng)前的會話數(shù)據(jù)并刪除會話的cookie,session,cookie一起干掉,刪除session表中session的整條數(shù)據(jù)。
    50.     request.session.flush()
    51.     '''
    52.     執(zhí)行以下操作:
    53.     1) request.COOKIE.get('sessionid'),獲得session_key
    54.     2) django_session表中刪除session_key對應(yīng)的記錄
    55.     3) response.delete_cookie('sessionid')
    56.     '''
    57.     return response

    打開登錄頁面,沒有攜帶任何cookie信息(csrf那個先不管)

    發(fā)起登錄請求,設(shè)置session信息,其中會生成隨機字符串比如mjx9gsq47ofwmcg2ubxtg28uk6idbq2a,然后以這個sessionid為key,這個字符串為value,設(shè)置cookie信息。

    并且在django_session插入記錄,其中session_key字段的值就是sessionid的值,session_data字段的值就是上面設(shè)置的session鍵值對。

    然后跳轉(zhuǎn)到home頁,就會攜帶cookie信息,獲取sessionid的值,在數(shù)據(jù)庫django_session表中查找是否有相關(guān)記錄。

    如果退出,則刪除session信息

    從DJANGO角度來看:

    第一次請求:

    ① 第一次請求,在請求頭中沒有攜帶任何cookie信息。

    ② 我們在設(shè)置session的時候,session會做2件事。

    第一件:將數(shù)據(jù)保存在數(shù)據(jù)庫中。

    第二件:設(shè)置一個cookie信息,這個cookie信息是以sessionid為key,value為xxxx,cookie肯定會以響應(yīng)的形式在響應(yīng)頭中出現(xiàn)。

    第二次以及之后的請求:

    ③ 都會攜帶cookie信息,特別是sessionid。

    如果換了瀏覽器,還能獲取到session信息嗎?

    解:不可以,因為session依賴于cookie,換了瀏覽器,都沒有cookie信息了。


    文章題目:Django框架之會話技術(shù)之Cookie與Session
    本文地址:http://www.dlmjj.cn/article/dhdddhp.html