Django Session Cookie使用
一、cookie和session說明
由於http是無狀態的協議,不像tcp一樣可以保持連線,那麼這個時候使用者在通過http協議訪問時,伺服器並不知道具體是哪個使用者,導致無法根據某種狀態做一些特殊的處理,那麼這個時候,cookie就產生了
cookie就是伺服器基於不同的使用者或者使用者不同的狀態進行區分,進而執行不同的操作,如可以根據使用者cookie進行判定使用者是否登入,也可以通過web伺服器來根據不同的cookie定義做一些規則過
cookie雖然在一定程度上解決了“保持狀態”的需求,但是由於cookie本身最大支援4096位元組,以及cookie本身儲存在客戶端,可能被攔截或竊取,因此就需要有一種新的東西,它能支援更多的位元組,並且他儲存在伺服器,有較高的安全性。這就是session
問題來了,基於http協議的無狀態特徵,伺服器根本就不知道訪問者是“誰”。那麼上述的cookie就起到橋接的作用。
我們可以給每個客戶端的cookie分配一個唯一的id,這樣使用者在訪問時,通過cookie,伺服器就知道來的人是“誰”。然後我們再根據不同的cookie的id,在伺服器上儲存一段時間的私密資料,如“賬號密碼”等等。
總結而言:cookie彌補了http無狀態的不足,讓伺服器知道來的人是“誰”;但是cookie以文字的形式儲存在本地,自身安全性較差;所以我們就通過cookie識別不同的使用者,對應的在session裡儲存私密的資訊以及超過4096位元組的文字。
另外,上述所說的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}
三、Django 基於cookie和session的認證
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
user = request.POST.get('user', None)
password =request.POST.get('password', None)
if user == 'root' and password == '123':
# 1、生成隨機字串, 該隨機字串作為cookie的value及session的key
# 2、將生成的字串傳給使用者瀏覽器cookie
# 3、定義session資訊, 定義session_key為隨機字串,session_data為base64加密的使用者資訊
request.session['username'] = user
request.session['is_login'] = True
if request.POST.get('none_login', None):
# 獲取使用者選中的登入時長並設定超時時間
request.session.set_expiry(3600*24*30)
return redirect('/page/index/')
else:
return render(request, 'login.html')
def index(request):
if request.session.get('username', None):
return render(request, 'index.html')
else:
return redirect('/page/login/')
四、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()
# 使用者session的隨機字串
request.session.session_key
# 將所有session失效日期小於當前日期的資料刪除
request.session.clear_expired()
# 檢查使用者session的隨機字串,在資料庫中是否存在
request.session.exists('session_key')
# 先獲取當前使用者的session-id,然後進行刪除這個session, 使用者登出用
request.session.clear()
# 刪除當前使用者的所有session資料
request.session.delete('session_key')
request.session.set_expiry(value)
* 如果value是個整數,session會在多少些秒後失效
* 如果value是個datetime或timedelta,session就會在這個時間後失效
* 如果value是0,使用者關閉瀏覽器session就會失效
* 如果value是None,session會依賴全域性session失效策略
PS: cookie中不設定超時時間,則表示關閉瀏覽器自動清除
session過期時間預設為兩週(django)
五、session的一般配置
定義session的cookie儲存在瀏覽器端的名稱,預設為sessionid (預設)
SESSION_COOKIE_NAME = ‘sessionid’
設定session的cookie的失效日期(預設)
SESSION_COOKIE_AGE = 1209600
設定session的cookie的作用域(預設)
SESSION_COOKIE_DOMAIN = None
設定是否https傳輸cookie(預設)
SESSION_COOKIE_SECURE = False
設定session的cookie儲存的路徑(預設)
SESSION_COOKIE_PATH = ‘/’
設定是否session的cookie只支援http(預設)
SESSION_COOKIE_HTTPONLY = True
是否每次請求都儲存session(預設)(如果改引數為true,則每次請求的時候session過期時間會進行重置,並且使用者瀏覽器cookie過期時間也會重置)
SESSION_SAVE_EVERY_REQUEST = False
是否關閉瀏覽器都使得session(預設)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
定義session的儲存是否為file(預設)
SESSION_FILE_PATH = None
序列化session儲存資料(預設)
SESSION_SERIALIZER = ‘django.contrib.sessions.serializers.JSONSerializer’
六、session的引擎配置
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
6.1 快取 session
SESSION_ENGINE = ‘django.contrib.sessions.backends.cache’ # 引擎
SESSION_CACHE_ALIAS = ‘default’ # cache使用default的配置,default位於CACHES中的default
例如: 將快取內容儲存至記憶體
CACHES = {
'default1': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
例如: 將快取內容儲存至memcache
CACHES = {
'default2': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
例如: 將快取內容儲存至redis(django預設不支援redis,需要安裝django-redis)
CACHES = {
"default3": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"PASSWORD": "xxxxxxx",
}
}
}
6.2 檔案session
SESSION_ENGINE = ‘django.contrib.sessions.backends.file’ # 引擎
SESSION_FILE_PATH = None # 快取檔案路徑,如果為None,則使用tempfile模組獲取一個臨時地址tempfile
SESSION_FILE_PATH = os.path.join(BASE_DIR, ‘cache’)
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}
6.3 快取加資料庫
快取加資料庫session(先去快取裡面拿,如果沒有則去資料庫裡面拿)
SESSION_ENGINE = ‘django.contrib.sessions.backends.cached_db’ # 引擎
6.4 加密cookie session
SESSION_ENGINE = ‘django.contrib.sessions.backends.signed_cookies’ # 引擎