Django 框架5-cookie和session

爲什麼會有cookie和session?

    瀏覽器向服務器發送http請求,建立session(會話),服務器返回完成,session結束,瀏覽器與服務斷開

    再次發送http請求,重新建立會話,這就會出現用戶信息丟失,服務器不能對請求的信息進行區分。

    A登陸帳戶,服務器驗證後,結束連接,A登陸的信息兩邊都沒有記錄,A再點其它連接,服務器就不知道是誰點的。。。

 

cookie和session是什麼?

    爲了跟蹤用戶和服務器之間的連接狀態,先出現了cookie(存在客戶端),後來發現不太安全,又出現了session(存在)

    Cookie通過在客戶端記錄信息確定用戶身份,Session通過在服務器端記錄信息確定用戶身份。

 

一、cookie

    cookie信息以鍵值對的形式記錄在客戶端

    可以被修改

    瀏覽器提交請求自動附加cookie信息

    ※最大支持4096字節

    不可以跨域共享,比如京東不會識別到已登陸淘寶的用戶信息

 

    1、設置cookie

        普通設置:set_cookie

        格式:set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False)

        注意:set_cookie是HttpResponse方法,所以只能用於redirect和HttpResponse,render沒有此方法


         帶加密的:set_signed_cookie,使用salt字符串進行簽名認證,不僅檢測cookie值,還檢測salt生成的簽名字符串

set_signed_cookie(key, value='', salt,max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False)

        選項功能:

參數作用
name該Cookie的名稱。Cookie一旦創建,名稱便不可更改
value該Cookie的值。如果值爲Unicode字符,需要爲字符編碼。如果值爲二進制數據,則需要使用BASE64編碼
maxAge該Cookie失效的時間,單位秒。如果爲正數,則該Cookie在maxAge秒之後失效。如果爲負數,該Cookie爲臨時Cookie,關閉瀏覽器即失效,瀏覽器也不會以任何形式保存該Cookie。如果爲0,表示刪除該Cookie。默認爲–1,常用max_age = 60*60*24(一天)
expires

1、可以爲秒,expires

2、可以爲datetime時間格式

3、datime格式的字符串--源碼裏直接使用self.cookie[value]['expires']=str來設置,

      但是,並不生效,待探討

需要注意的是服務器和客戶端時間不同步問題

secure該Cookie是否僅被使用安全協議傳輸。安全協議。安全協議有HTTPS,SSL等,在網絡上傳輸數據之前先將數據加密。默認爲false。當使用https式,必須要secure設置爲Y=True。
path該Cookie的使用路徑。如果設置爲“/sessionWeb/”,則只有contextPath爲“/sessionWeb”的程序可以訪問該Cookie。如果設置爲“/”,則本域名下contextPath都可以訪問該Cookie。注意最後一個字符必須爲“/”
domain可以訪問該Cookie的域名。如果設置爲“.google.com”,則所有以“google.com”結尾的域名都可以訪問該Cookie。注意第一個字符必須爲“.”
httponly限制在瀏覽器控制檯獲取鍵值對,但無法對抓包工具進行限制。
salt參數是字符串,加密cookie,客戶端顯示的是無序的cookie值。僅在set_signed_cookie下有效
# django views.py

def login(request):
    user = request.GET.get('user',None)    # 獲取值,如果沒有,賦值None
    pw = request.GET.get('pw',None)

    if user=='david' and pw=='123456':
        res = redirecte('index/') 
        res.set_cookie('username',user)    
        # 基於httpresponse類設置cookie
        
        res.set_signed_cookie('pw','123456',salt="lakjsdfh") 
        # 使用salt生成簽名,服務端使用get_signed_cookie獲取,使用相同的salt進行簽名認證
        
    else:
        res = redirecte('/djhw/')          # 用戶名和密碼不對則返回主頁
    
    return res

 

    2、讀取cookie

            request.COOKIE.get():讀取普通的cookie

            request.get_signed_cookie(),讀取帶簽名的cookie,注意:要想設置默認值,寫default=‘’

def index(request):
    user = request.COOKIE.get('user',None)    # 獲取cookie,如果沒有,賦值None
    
    pw = request.COOKIE.get('pw',None)        
    # 獲取到的是:123456:加密的簽名字符串
    
    pw = request.get_signed_cookie('pw',None,salt)      
    # 使用salt,獲取到的是:123456
    
    if user == 'david' and pw == '123456':    # 判斷獲取的cookie是否和之前設置的一樣
        return render(request, 'hw/index.html')    # 如果一樣,進入index頁面
    else:
        return redirect('/djhw/')                  # 如果不一樣,進入登陸面頁

 

     3、刪除cookie,delete_cookie()

res = redirect('/djhw/')
res.delete_cookie('user_name')

 

    4、使用裝飾器認證

#FBV
def auth(func):
    def inner(request, *args, **kwargs)
        username = request.COOLIES.get('user_name')    # 讀取用戶名
        if username:        
            return func(request, *args, **kwargs)      # 如果存在,返回傳入的func函數
        else:
            return redirect('/djhw/')                  # 如果不存在,返回首頁(登陸頁)
    return inner                                       # 返回結果
    
    
#CBV
import django.utils.decorators import method_decorator
form django import views

方法一:使用類裝飾器
@method_decorator(auth,name='dispatch')
class Blog(views.View):
    def get(self,request):
        username=request.COOKIES.get('user_name')
        return render(request,'hw/index.html')
        
方法二:
class Blog(views.View):
    # 因爲所有方法都是dispatch方法註冊的,只裝飾dispatch,所有方法都被裝飾。
    @auth
    def dispatch(self,request,*args,**kwargs):
        return super(Blog.self).dispatch(request,*args,**kwargs)

    def get(self,request):
        username=request.COOKIES.get('user_name')
        return render(request,'hw/index.html')

 

session

 

    session信息以鍵值對的形式記錄在服務端,存儲位置可以在數據庫、內存、文件

    ※服務端給用戶所回一個隨機字符串,客戶端在Cookies中存儲這個隨機串

    ※客戶端下次提交包含隨機字符串,通過隨機字符串獲取session


    1、設置Session鍵值

        session是基於request的方法

def login(request):
    # 設置和讀取session鍵值
    request.session['key1']='value1'              # 增加key1,如果鍵存在,更新值
    request.session.setdefault('key2', 'value2')  # 增加key2,如果存在,不設置value2
    request.session.get('key3','value3')    # key3存在,獲取;不存在,增加key3,值爲'value'
    request.session['key1']                 # 獲取Key1的值,如果不存在報錯
    
    # 查詢是否存在session ID
    request.session.exists('session id')    # 可用於數據庫+緩存方式,緩存沒有找數據庫
    
    # 設置session生效時間
    request.session.set_expiry(value)    # 設置生效時長,value單位秒
        # 如果value是個整數,session會在多少些秒後失效
        # 如果value是個datetime或timedelta,session就會在這個時間後失效
        # 如果value是0,用戶關閉瀏覽器session就會失效
        # 如果value是None,session會依賴全局session失效策略
        
    request.session.clear_expired()        # datetime日期,把生效日期小於當前日期的session刪除
        
    
    # 刪除
    del request.session['key1']    # 刪除session鍵
    request.session.clear()        # 刪除所有session鍵,session ID保留 
    request.session.delete()       # 刪除當前session ID,參數可以放session ID,用戶logout時用
    
    # 查看session
    request.session.items()        # 把鍵值對以列表顯示[(k1,v1),(k2,v2)]
    request.session.keys()         # 顯示所有keys,[k1,k2]
    request.session.values()       # 顯示所有values,[v1,v2]

    # 查看當前請求的session_id
    request.session.session_key    # 存儲在cookies的加密session ID

    2、session的全局配置:

        在settings.py文件中可以對session進行全局配置

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,默認修改之後才保存(默認)

    3、session的存儲位置

        在settings.py文件中配置引擎,可以輕鬆改變session的存儲位置

SESSION_ENGINE = 'django.contrib.sessions.backends.db'                    # 數據庫(默認)
SESSION_ENGINE = 'django.contrib.sessions.backends.file'                  # 文件
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'                 # 緩存
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'             # 緩存數據庫
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'        # 加密cookie

 

    4、session保存在緩存(內存、memcache、redis)

        settings.py配置:

SESSION_ENGINE = 'django.contrib.sessions.babckends.cache'    # 設置引擎(緩存)
SESSION_ENGINE = 'django.contrib.sessions.babckends.cache_db'    
# 設置引擎(緩存+數據庫),緩存找不到,去數據庫找

SESSION_CACHE_ALIAS = 'default'            # 指定CACHES裏面的配置項名
# CACHES裏面可以有多項,但只有一個生效
CACHES = {    
    'default':{        # 保存在內存
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
    }
    'memcache':{        # 保存在內存
    'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
    'LOCATION': ['ip1:port','ip2:port',],
    }
    
    'redis':{          # 保存在redis,django需要pip3 install django_redis安裝
    'BACKEND': 'django_redis.cache.RedisCache',
    'LOCATION': 'redis://密碼@IP:PORT/1',
    'OPTIONS': {'CLIENT_CLASS':'django_redis.client.DefaultClient'},

    }    

}

 

    5、存儲到文件

        settings.py

SESSION_ENGINE = 'django.contrib.sessions.backends.file'
SESSION_FILE_PATH = None             # 緩存文件路徑,如果爲None,則使用tempfile模塊獲取一個臨時地址tempfile
# SESSION_FILE_PATH = os.path.join(BASE_DIR, 'cache')
SESSION_CACHE_ALIAS = 'default'            # 指定CACHES裏面的配置項名
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',
    }
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章