cookie和session有著千絲萬縷的關係
cookie和session區別
儲存位置的不同
cookie
儲存在瀏覽器客戶端session
儲存在服務端(可以是php伺服器,redis,資料庫)儲存的容量不同
單個cookie
儲存的資料<=4KB,一個站點最多儲存20個Cookie(瀏覽器不同而不同)。session
原則上沒有限制,但是考慮到伺服器的效能,不宜儲存過多的資訊,並要有適當的刪除機制儲存資料格式不同
cookie
只能保管ASCII字串,並需要透過編碼方式儲存為Unicode字元或者二進位制資料session
中能夠儲存任何型別的資料,包括且不限於string,integer,list,map等隱私策略不同
cookie
對客戶端是可見的,別有用心的人可以分析存放在本地的cookie並進行cookie欺騙,所以它是不安全的。session
儲存在伺服器上,對客戶端是透明對,不存在敏感資訊洩漏的風險。有效期上不同
程式可以透過設定cookie的過期時間,達到使cookie長期有效的效果。session
依賴於名為JSESSIONID的cookie,而cookie JSESSIONID的過期時間預設為-1,只需關閉視窗該session就會失效,因而session不能達到長期有效的效果。伺服器壓力不同
cookie
保管在客戶端,不佔用伺服器資源。對於併發使用者十分多的網站,cookie是很好的選擇。session
是保管在伺服器端的,每個使用者都會產生一個session。假如併發訪問的使用者十分多,會產生十分多的session,耗費大量的記憶體。瀏覽器支援不同
假如客戶端瀏覽器不支援cookie:
cookie是需要客戶端瀏覽器支援的,假如客戶端禁用了cookie,或者不支援cookie,則會話跟蹤會失效。關於WAP上的應用,常規的cookie就派不上用場了。
運用session需要使用URL地址重寫的方式。一切用到session程式的URL都要進行URL地址重寫,否則session會話跟蹤還會失效。假如客戶端支援cookie:
cookie既能夠設為本瀏覽器視窗以及子視窗內有效,也能夠設為一切視窗內有效。
session只能在本視窗以及子視窗內有效。
跨域支援上的不同
cookie支援跨域名訪問,例如將domain屬性設定為“.baidu.com”,則以“.baidu.com”為字尾的一切域名均能夠訪問該Cookie。跨域名Cookie如今被普遍用在網路中。
而Session則不會支援跨域名訪問。Session僅在他所在的域名內有效。
當瀏覽器禁用cookie後如何獲取到session
我們知道,當在伺服器端啟用session時候,資料預設是以檔案的形式儲存伺服器上的,其中session_name(預設是PHPSESSID)和session_id是儲存在COOKIE中的,併傳送到Client端。此時,使用者訪問其他頁面傳送HTTP請求時候依然將cookie中儲存的session_name和session_id帶回伺服器端,而伺服器這時候同樣啟用了session,就會將session_id對應的檔案中儲存的資料反序列化並儲存到$_SESSION
陣列中。整個流程大概是這樣子的。
有一天,客戶端無意將COOKIE禁用了,這時候再去伺服器端訪問上面流程的程式會出現這樣的情況。伺服器同樣會儲存session資料到檔案中(預設),但是設定的cookie頭資訊卻無法在客戶端儲存,後面再去訪問其他頁面時候客戶端也就沒有帶上cookie中的資料去傳送請求,然後伺服器也就無法獲取cookie資訊,造成的後果就是上次建立的session檔案成為了垃圾資料,而每次請求都要重新建立session檔案,然後一直迴圈~~ 無法跟蹤使用者登入狀態,造成不好的使用者體驗。
透過php.ini設定來解決
- 在瀏覽器開啟cookie時候使用cookie儲存會話資訊,當瀏覽器禁用cookie時候使用url傳遞會話資訊
#在php.ini檔案中修改 session.use_trans_sid=1 //啟用url傳遞會話資訊 session.use_only_cookies=0 //關閉只是用cookie儲存會話資訊 session.use_cookies=1 //預設使用cookie儲存會話資訊
- 不管瀏覽器是否開啟cookie,都使用url的方式傳遞會話資訊
測試#在php.ini檔案中 session.use_trans_sid=1 //啟用url傳遞會話資訊 session.use_only_cookies=0 //關閉只是用cookie儲存會話資訊 session.use_cookies=0 //不使用cookie儲存會話資訊
//set.php ini_set('session.use_trans_sid', 1); ini_set('session.use_only_cookies', 0); ini_set('session.use_cookies', 0);//全部使用url傳遞會話資訊 session_start(); $sid = session_id(); $_SESSION['abc'] = ['value','value2']; echo '<a href="get.php">get</a>';
//get.php session_id($_GET[session_name()]); session_start(); var_dump($_GET[session_name()],$_SESSION, $_COOKIE); //可以獲取到session
- 在瀏覽器開啟cookie時候使用cookie儲存會話資訊,當瀏覽器禁用cookie時候使用url傳遞會話資訊
手動URL傳值
為每個連結加上引數,引數值為session_id
示例session_start();//啟動session $sid = session_id(); $_SESSION['abc'] = ['value','value2'];//設定session $_SESSION['abc2'] = new stdClass();//設定session echo '<a href="get.php?sid='.$sid.'">get</a>';//將引數透過get的方式傳遞
session_id($_GET['sid']);//獲取session_id, 必須在呼叫 session_start() 函式之前呼叫 session_id() 函式,否則無法使用該session_id session_start();//開啟session var_dump($_GET['sid'], $_SESSION);
過隱藏表單傳遞
在表單中隱藏提交session_id在資料庫中儲存session_id, 然後手動呼叫
Note: 基於 URL 的會話管理比基於 cookie 的會話管理有更多安全風險。例如使用者有可能透過 email 將一個包含有效的會話 ID 的 URL 發給他的朋友,或者使用者有可能在收藏夾中存有一個包含會話 ID 的 URL 來以同樣的會話 ID 去訪問站點。
本作品採用《CC 協議》,轉載必須註明作者和本文連結