前言
session: session
和cookie
的作用有點類似,都是為了存儲用戶相關的信息。不同的是,cookie
是存儲在本地瀏覽器,session
是一個思路、一個概念、一個服務器存儲授權信息的解決方案,不同的服務器,不同的框架,不同的語言有不同的實現。雖然實現不一樣,但是他們的目的都是服務器為了方便存儲數據的。session
的出現,是為了解決cookie存儲數據不安全
的問題的。
cookie和session的使用
web開發發展至今,cookie
和session
的使用已經出現了一些非常成熟的方案。在如今的市場或者企業里,一般有兩種存儲方式:
- 存儲在服務端:通過
cookie
存儲一個sessionid
,然后具體的數據則是保存在session
中。如果用戶已經登錄,則服務器會在cookie
中保存一個sessionid
,下次再次請求的時候,會把該sessionid
攜帶上來,服務器根據sessionid
在session庫中獲取用戶的session數據。就能知道該用戶到底是誰,以及之前保存的一些狀態信息。這種專業術語叫做server side session。Django把session
信息默認存儲到數據庫中,當然也可以存儲到其他地方,比如緩存中,文件系統中等。存儲在服務器的數據會更加的安全,不容易被竊取。但存儲在服務器也有一定的弊端,就是會占用服務器的資源,但現在服務器已經發展至今,一些session
信息還是綽綽有余的。 - 將
session
數據加密,然后存儲在cookie
中。這種專業術語叫做client side session
。flask
框架默認采用的就是這種方式,但是也可以替換成其他形式。
django中應用session
1.啟用session
要應用session
,必須開啟session
中間層,在settings
中:
MIDDLEWARE = [
# 啟用 Session 中間層
'django.contrib.sessions.middleware.SessionMiddleware',
]
2.session的5種存儲機制
默認情況下,session
數據是存儲到數據庫中的。我們如何得知呢?可以從Django的默認配置中查看到,Django的默認配置路徑是from django.conf import global_settings
,我們可以打開然后查看到默認配置,代碼如下:
# Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認)
SESSION_COOKIE_NAME = 'sessionid'
# Session的cookie失效日期(2周)(默認)
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
# 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,默認修改之后才保存(默認)
SESSION_SAVE_EVERY_REQUEST = False
# 是否關閉瀏覽器使得Session過期(默認)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
# 存儲session數據默認使用的模塊
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
# session數據的序列化類
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
這里我們可以看到SESSION_ENGINE = 'django.contrib.sessions.backends.db'
django默認使用的是存儲到數據庫中,這只是存儲機制中的其中一種,下面我們逐一介紹
1.數據庫方式
使用數據庫。默認就是這種方案。
# 數據庫方式(默認):
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
# 數據庫類型的session引擎需要開啟此應用,啟用 sessions 應用
INSTALLED_APPS = [
'django.contrib.sessions',
]
2.緩存
使用緩存來存儲session
。想要將數據存儲到緩存中,前提是你必須要在settings.py
中配置好CACHES
,並且是需要使用Memcached
,而不能使用純內存作為緩存。
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
3.緩存+數據庫
在存儲數據的時候,會將數據先存到緩存中,再存到數據庫中。這樣就可以保證萬一緩存系統出現問題,session
數據也不會丟失。在獲取數據的時候,會先從緩存中獲取,如果緩存中沒有,那么就會從數據庫中獲取。
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
4.文件
使用文件來存儲session
。
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
# 設置文件位置, 默認是 tempfile.gettempdir(),
# linux下是:/tmp
# windows下是: C:\Users\51508\AppData\Local\Temp
SESSION_FILE_PATH = 'd:\session_dir'
5.加密cookie
基於cookie的session,所有數據都保存在cookie中,一般情況下不建議使用這種方式
- cookie有長度限制,4096個字節
- cookie不會因為服務端的注銷而無效,那么可能造成攻擊者使用已經登出的cookie模仿用戶繼續訪問網站
- SECRET_KEY這個配置項絕對不能泄露,否則會讓攻擊者可以遠程執行任意代碼
- cookie過大,會影響用戶訪問速度
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
3.操作session
- get:用來從session中獲取指定值。
- pop:從session中刪除一個值。
- keys:從session中獲取所有的鍵。
- items:從session中獲取所有的值。
- clear:清除當前這個用戶的session數據。
- flush:刪除session並且刪除在瀏覽器中存儲的
session_id
,一般在注銷的時候用得比較多。 - set_expiry(value):設置過期時間。
- 整形:代表秒數,表示多少秒后過期。
- 0:代表只要瀏覽器關閉,
session
就會過期。 - None:會使用全局的session配置。在settings.py中可以設置
SESSION_COOKIE_AGE
來配置全局的過期時間。默認是1209600
秒,也就是2周的時間。
- clear_expired:清除過期的
session
。Django並不會清除過期的session
,需要定期手動的清理,或者是在終端,使用命令行python manage.py clearsessions
來清除過期的session
。
實戰案例
session
其實本質也是基於cookie
使用的,使用起來跟session差不多,先創建3個路由地址
urlpatterns = [
path('set_session/', views.set_session, name='set_session'),
path('get_session/', views.get_session, name='get_session'),
path('clear_session/', views.clear_session, name='clear_session')
]
然后編寫對應的視圖
def set_session(request):
"""設置session"""
request.session["username"] = "jkc"
return HttpResponse("session_view")
def get_session(request):
"""獲取session"""
username = request.session.get("username")
return HttpResponse(f"session的值為{username}")
def clear_session(request):
"""清除session"""
request.session.clear()
return HttpResponse("清除session成功")
接着我們在瀏覽器上先打開F12,然后輸入url地址http://127.0.0.1:8000/session/set_session/
,我們可以看到響應頭中有后台返回的set-cookie
里面有個sessionid
,這個sessionid
就是前端傳給后台,后台經過一系列加密操作后返回給前端瀏覽器的key
因為我們django默認存儲session的機制是數據庫,所以數據庫中的django_session
表中也會有同樣key的一條數據
接着我們在瀏覽器上訪問http://127.0.0.1:8000/session/get_session/
,瀏覽器頁面上會返回session的值為jkc
,說明我們的session的key是正確的,且沒有過期。
最后再訪問http://127.0.0.1:8000/session/clear_session/
,瀏覽器頁面返回清除session成功
,如何證明呢?我們可以再次訪問http://127.0.0.1:8000/session/get_session/
,我們會發現這次返回的是session的值為None
,值為None
說明session已經被清空