本文執行個體講述了CodeIgniter配置之SESSION用法。分享給大家供大家參考,具體如下:
剛使用Codeigniter時也被其中的SESSION迷惑過,後來就再也沒用過CI內建的SESSION,想必還是有必要整理一下SESSION。為弄清CI中的SESSION,先來說一下PHP中SESSION是如何工作的。由於HTTP協議本身是無狀態的,所以當保留某個使用者的訪問狀態資訊時,需要用戶端有一個唯一標識傳給服務端,這個唯一標識就是SESSION ID,存放在用戶端的COOKIE中,然後服務端根據該標識讀取存放的使用者狀態資訊,達到儲存工作階段狀態的目的。PHP中啟動一個會話需要執行下面語句:
複製代碼 代碼如下:session_start();
1、用戶端每次請求時會有一些資訊存放中HTTP頭中發送給服務端,以使用者第一次訪問為例:
複製代碼 代碼如下:Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:s.local
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
2、服務端接到請求處理後並返回給用戶端,並在HTTP Response中加上添加COOKIE的請求,告訴瀏覽器需要設定一個COOKIE,COOKIE名為PHPSESSID,值為r887k5n4scg32d4ba34huuhmq7,如:
複製代碼 代碼如下:Response Headers
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Length:0
Content-Type:text/html
Date:Sun, 08 Dec 2013 12:56:56 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=5, max=100
Pragma:no-cache
Server:Apache/2.2.11 (Win32) PHP/5.4.7
Set-Cookie:PHPSESSID=r887k5n4scg32d4ba34huuhmq7; path=/
X-Powered-By:PHP/5.4.7
3、當用戶端再次訪問該網站的頁面時,瀏覽器會將該COOKIE發送給服務端,服務端根據COOKIE的值去讀取伺服器上存放SESSION的檔案,拿到到會話資訊,如:
複製代碼 代碼如下:Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:PHPSESSID=r887k5n4scg32d4ba34huuhmq7
Host:s.local
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63
從而達到儲存工作階段狀態的目的。但也需要注意,如果擷取到使用者A登入的SESSION ID會怎麼樣?根據上面的邏輯,如果在請求過程中把擷取到的SESSION ID一併發送給服務端,服務端根據SESSION ID讀取檔案,發現檔案內容存在,從而判定使用者為A使用者,也就是擷取到了A使用者的使用者狀態,從而可能可以進行一些敏感操作。所以在會話有效期間內,擷取到了SESSION ID即擷取到了使用者的授權,這是比較危險的,以本地的一個管理系統為例,通過chrome登入後查看到用戶端COOKIE如:
假如如果通過某種手段擷取到了SESSION ID, 可以類比發送一個相同的COOKIE過去即可實現登入。FireFox中可添加COOKIE,開啟Firebug後Cookies中建立cookie,確定之後重新整理頁面即可登入到管理系統,如:
通常情況下可通過js擷取到cookie,所以需要注意轉義,防止資料展示時被執行了。接下來看看CI中的SESSION。在設定檔中有幾個跟Session配置相關的參數,影響到Session的使用,它們是:
//session儲存在cookie中的名稱$config['sess_cookie_name'] = 'ci_session';//session的有效時間$config['sess_expiration'] = 7200;//是否關閉瀏覽器session失效$config['sess_expire_on_close'] = FALSE;//SESSION是否加密存放在COOKIE中$config['sess_encrypt_cookie'] = FALSE;//是否儲存在資料庫中$config['sess_use_database'] = FALSE;//存在資料庫中,則資料庫表名$config['sess_table_name'] = 'ci_sessions';//是否匹配IP$config['sess_match_ip'] = FALSE;//是否匹配UserAgent$config['sess_match_useragent'] = TRUE;//更新時間時間$config['sess_time_to_update'] = 300;
CI內建的SESSION沒有服務端檔案儲存體,所有的資訊都存放在用戶端COOKIE中,當調用$this->load->library('session');時會啟動一個會話,即設定一個COOKIE,COOKIE的內容如下:
Array([session_id] => f05138a9513e4928cb0a57672cfe3b53[ip_address] => 127.0.0.1[user_agent] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36[last_activity] => 1386569398[user_data] =>)
當用戶端請求時會將這些資訊在HTTP頭中傳輸給服務端,服務端從HTTP頭中讀取到SESSION資訊。同樣的可以實現會話,但該方式有很多的不確定因素,根據源碼說幾點吧:
1、如果記錄檔中出現:The session cookie data did not match what was expected. This could be a possible hacking attempt.說明兩個問題:a.sess_encrypt_cookie為false,SESSION在COOKIE中未加密存放 b.讀取到COOKIE後,校正失敗。涉及到加解密、參數處理的情況,容易出現匹配不通過的情況,若不通過則清空SESSION。
2、如果sess_match_ip為true,當用戶端IP變化時,SESSION將校正不通過,從而清空SESSION。
3、sess_match_useragent預設為true,當用戶端UserAgent變化時,校正不通過,清空SESION。簡單的例子,通過IE瀏覽器訪問,若切換到不同的IE模式,Agent不同,所以校正不通過,清空SESSION。
可以看到,當出現上面任何一種情況時,SESSION都會清空,出現登入不成功或者跳轉到登入頁面的情況。如果說不加密、不校正IP、UserAgent呢?因為COOKIE是存放在用戶端,需要伴隨HTTP請求發給服務端,一來過多的COOKIE會影響速度,對一些圖片等資源來說完全時浪費頻寬;二來COOKIE只能儲存4K的資料,加密處理後能存放的更小。
種種的不確定因素將產生各種奇怪的問題,避免過多的糾結,果斷改用其他方式吧。
更多關於CodeIgniter架構相關內容感興趣的讀者可查看本站專題:《codeigniter入門教程》
希望本文所述對大家基於CodeIgniter架構的PHP程式設計有所協助。