天天看點

Django之COOKIE與SESSION

COOKIE與SESSION簡介:

1、cookie不屬于http協定範圍,由于http協定無法保持狀态,但實際情況,我們卻又需要‘保持狀态’,是以cookie就是在這個場景下誕生。

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

2、cookie雖然在一定程度上解決了‘保持狀态’的需求,但是由于cookie本身最大支援4096位元組,以及cookie本身儲存在用戶端,可能被攔截或竊取,是以就需要有一種新的東西,它能支援更多的位元組,并且他儲存在伺服器,有較高的安全性。這就是session。

問題來了,基于http協定的無狀态特性,伺服器根本就不知道通路者是‘誰’。那麼上述的cookie就起到橋接的作用。

我們可以給每隔用戶端的cookie配置設定一個唯一的id,這樣使用者在通路時,通過cookie,伺服器就知道來的人是‘誰’。然後我們再根據不同的cookie的id,在伺服器上儲存一段時間的私密資料,如“帳号密碼”等。

3、總結而言:cookie彌補了http無狀态的不足,讓伺服器知道來的人是“誰”;但是cookie以文本的形式儲存在本地,自身安全性比較差,是以我們就通過cookie識别不同的使用者,對應的在session裡儲存私密的資訊以及超過4096位元組的文本。

4、另外、上述cookie和session是共同性的東西,不限于語言和架構

認證應用

前幾節的介紹中我們已經有能力制作一個登陸頁面,在驗證了使用者名和密碼的正确性後跳轉到背景的頁面。但是測試後也發現,如果繞過登陸頁面。直接輸入背景的url位址也可以直接通路的。這個顯然是不合理的。其實我們缺失的就是cookie和session配合的驗證。有了這個驗證過程,我們就可以實作和其他網站一樣必須登入才能進入背景頁面了。

先說一下這種認證的機制。每當我們使用一款浏覽器通路一個登陸頁面的時候,一旦我們通過了認證。伺服器端就會發送一組随機唯一的字元串(假設是123abc)到浏覽器端,這個被存儲在浏覽端的東西就叫cookie。而伺服器端也會自己存儲一下使用者目前的狀态,比如login=true,username=hahaha之類的使用者資訊。但是這種存儲是以字典形式存儲的,字典的唯一key就是剛才發給使用者的唯一的cookie值。那麼如果在伺服器端檢視session資訊的話,理論上就會看到如下樣子的字典

{'123abc':{'login':true,'username:hahaha'}}

因為每個cookie都是唯一的,是以我們在電腦上換個浏覽器再登陸同一個網站也需要再次驗證。那麼為什麼說我們隻是理論上看到這樣子的字典呢?因為處于安全性的考慮,其實對于上面那個大字典不光key值123abc是被加密的,value值{'login':true,'username:hahaha'}在伺服器端也是一樣被加密的。是以我們伺服器上就算打開session資訊看到的也是類似與以下樣子的東西

{'123abc':dasdasdasd1231231da1231231}

Cookie是什麼?

  儲存在用戶端浏覽器上的鍵值對

Session是什麼?

  儲存在服務端的資料(本質是鍵值對) 應用:依賴cookie ; 作用:保持會話(web網站); 好處:敏感資訊不會直接給用戶端

如下測試session 驗證代碼:

from django.shortcuts import render,HttpResponse,redirect
from app01 import models
def test(request):

    # models.UserInfo.objects.create(username='root',email='qweqweq')
    # models.UserInfo.objects.create(username='xxx',email='xxx',ctime='2011-11-11')
    # return HttpResponse('...')
    # v = {'k1':'v1','k2':'v2'}
    # for i in v.values():
    #
    # return render(request,'test.html',{'name':'fangsaowei'})
    response = HttpResponse('内容')
    response.set_cookie('k1','v1')
    response.set_cookie('k2','v2')
    response.set_cookie('k3','v3')
    response.set_cookie('k4','v4')
    return response


def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    else:
        u = request.POST.get('user')
        p = request.POST.get('pwd')
        obj = models.UserAdmin.objects.filter(username=u,password=p).first()
        if obj:
            # 1. 生成随機字元串
            # 2. 通過cookie發送給用戶端
            # 3. 服務端儲存
            # {
            #   随機字元串1: {'username':'alex','email':x''...}
            # }
            request.session['username'] = obj.username
            return redirect('/index/')
        else:
            return render(request,'login.html',{'msg':'使用者名或密碼錯誤'})


def index(request):
    # 1. 擷取用戶端端cookie中的随機字元串
    # 2. 去session中查找有沒有随機字元
    # 3. 去session對應key的value中檢視是否有 username
    v = request.session.get('username')
    if v:
        return HttpResponse('登入成功:%s' %v)
    else:
        return redirect('/login/')      

 Django中Cookie和Session補充:

Cookie

1、擷取Cookie:

request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    參數:
        default: 預設值
           salt: 加密鹽
        max_age: 背景控制過期時間      

2、設定Cookie:

rep = HttpResponse(...) 或 rep = render(request, ...)
 
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密鹽',...)
    參數:
        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儲存在用戶端的電腦上,是以,JavaScript和jquery也可以操作cookie。

<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num", 30,{ path: '/' });      

Session

Django中預設支援Session,其内部提供了5種類型的Session供開發者使用:

  • 資料庫(預設)
  • 緩存
  • 檔案
  • 緩存+資料庫
  • 加密cookie

1、資料庫Session

Django之COOKIE與SESSION
Django之COOKIE與SESSION
Django預設支援Session,并且預設是将Session資料存儲在資料庫中,即:django_session 表中。
 
a. 配置 settings.py
 
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(預設)
     
    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie儲存在浏覽器上時的key,即:sessionid=随機字元串(預設)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie儲存的路徑(預設)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie儲存的域名(預設)
    SESSION_COOKIE_SECURE = False                            # 是否Https傳輸cookie(預設)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie隻支援http傳輸(預設)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(預設)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否關閉浏覽器使得Session過期(預設)
    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次請求都儲存Session,預設修改之後才儲存(預設)
 
 
 
b. 使用
 
    def index(request):
        # 擷取、設定、删除Session中資料
        request.session['k1']
        request.session.get('k1',None)
        request.session['k1'] = 123
        request.session.setdefault('k1',123) # 存在則不設定
        del request.session['k1']
 
        # 所有 鍵、值、鍵值對
        request.session.keys()
        request.session.values()
        request.session.items()
        request.session.iterkeys()
        request.session.itervalues()
        request.session.iteritems()
 
 
        # 使用者session的随機字元串
        request.session.session_key
 
        # 将所有Session失效日期小于目前日期的資料删除
        request.session.clear_expired()
 
        # 檢查 使用者session的随機字元串 在資料庫中是否
        request.session.exists("session_key")
 
        # 删除目前使用者的所有Session資料
        request.session.delete("session_key")
 
        request.session.set_expiry(value)
            * 如果value是個整數,session會在些秒數後失效。
            * 如果value是個datatime或timedelta,session就會在這個時間後失效。
            * 如果value是0,使用者關閉浏覽器session就會失效。
            * 如果value是None,session會依賴全局session失效政策。      

View Code

2、緩存Session

Django之COOKIE與SESSION
Django之COOKIE與SESSION
a. 配置 settings.py
 
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    SESSION_CACHE_ALIAS = 'default'                            # 使用的緩存别名(預設記憶體緩存,也可以是memcache),此處别名依賴緩存的設定
 
 
    SESSION_COOKIE_NAME = "sessionid"                        # Session的cookie儲存在浏覽器上時的key,即:sessionid=随機字元串
    SESSION_COOKIE_PATH = "/"                                # Session的cookie儲存的路徑
    SESSION_COOKIE_DOMAIN = None                              # Session的cookie儲存的域名
    SESSION_COOKIE_SECURE = False                             # 是否Https傳輸cookie
    SESSION_COOKIE_HTTPONLY = True                            # 是否Session的cookie隻支援http傳輸
    SESSION_COOKIE_AGE = 1209600                              # Session的cookie失效日期(2周)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                   # 是否關閉浏覽器使得Session過期
    SESSION_SAVE_EVERY_REQUEST = False                        # 是否每次請求都儲存Session,預設修改之後才儲存
 
 
 
b. 使用
 
    同上      

3、檔案Session

Django之COOKIE與SESSION
Django之COOKIE與SESSION
a. 配置 settings.py
 
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 緩存檔案路徑,如果為None,則使用tempfile子產品擷取一個臨時位址tempfile.gettempdir()                                                            # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T
 
 
    SESSION_COOKIE_NAME = "sessionid"                          # Session的cookie儲存在浏覽器上時的key,即:sessionid=随機字元串
    SESSION_COOKIE_PATH = "/"                                  # Session的cookie儲存的路徑
    SESSION_COOKIE_DOMAIN = None                                # Session的cookie儲存的域名
    SESSION_COOKIE_SECURE = False                               # 是否Https傳輸cookie
    SESSION_COOKIE_HTTPONLY = True                              # 是否Session的cookie隻支援http傳輸
    SESSION_COOKIE_AGE = 1209600                                # Session的cookie失效日期(2周)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                     # 是否關閉浏覽器使得Session過期
    SESSION_SAVE_EVERY_REQUEST = False                          # 是否每次請求都儲存Session,預設修改之後才儲存
 
b. 使用
 
    同上      

4、緩存+資料庫Session

Django之COOKIE與SESSION
Django之COOKIE與SESSION
資料庫用于做持久化,緩存用于提高效率
 
a. 配置 settings.py
 
    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
 
b. 使用
 
    同上      

5、加密cookie Session

Django之COOKIE與SESSION
Django之COOKIE與SESSION
a. 配置 settings.py
     
    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
 
b. 使用
 
    同上      
def login(func):
    def wrap(request, *args, **kwargs):
        # 如果未登陸,跳轉到指定頁面
        if request.path == '/test/':
            return redirect('http://www.baidu.com')
        return func(request, *args, **kwargs)
    return wrap      

繼續閱讀