剛使用Codeigniter時也被其中的SESSION迷惑過,後來就再也沒用過CI自帶的SESSION,想必仍是有必要整理一下SESSION。爲弄清CI中的SESSION,先來講一下PHP中SESSION是如何工做的。因爲HTTP協議自己是無狀態的,因此當保留某個用戶的訪問狀態信息時,須要客戶端有一個惟一標識傳給服務端,這個惟一標識就是SESSION ID,存放在客戶端的COOKIE中,而後服務端根據該標識讀取存放的用戶狀態信息,達到保存會話狀態的目的。PHP中啓動一個會話須要執行下面語句:php
1
|
session_start();
|
一、客戶端每次請求時會有一些信息存放中HTTP頭中發送給服務端,以用戶第一次訪問爲例:html
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.36web
二、服務端接到請求處理後並返回給客戶端,並在HTTP Response中加上添加COOKIE的請求,告訴瀏覽器須要設置一個COOKIE,COOKIE名爲PHPSESSID,值爲r887k5n4scg32d4ba34huuhmq7,如:chrome
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數據庫
三、當客戶端再次訪問該網站的頁面時,瀏覽器會將該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以下圖:cookie
假如若是經過某種手段獲取到了SESSION ID, 能夠模擬發送一個相同的COOKIE過去便可實現登陸。FireFox中可添加COOKIE,打開Firebug後Cookies中新建cookie,肯定以後刷新頁面便可登陸到管理系統,以下圖:session
一般狀況下可經過js獲取到cookie,因此須要注意轉義,防止數據展現時被執行了。接下來看看CI中的SESSION。在配置文件中有幾個跟Session配置相關的參數,影響到Session的使用,它們是:併發
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//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信息。一樣的能夠實現會話,但該方式有不少的不肯定因素,根據源碼說幾點吧:
一、 若是日誌文件中出現: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。
二、若是sess_match_ip爲true,當客戶端IP變化時,SESSION將校驗不經過,從而清空SESSION。
三、sess_match_useragent默認爲true,當客戶端UserAgent變化時,校驗不經過,清空SESION。簡單的例子,經過IE瀏覽器訪問,若切換到不一樣的IE模式,Agent不一樣,因此校驗不經過,清空SESSION。
能夠看到,當出現上面任何一種狀況時,SESSION都會清空,出現登陸不成功或者跳轉到登陸頁面的狀況。若是說不加密、不校驗IP、UserAgent呢?由於COOKIE是存放在客戶端,須要伴隨HTTP請求發給服務端,一來過多的COOKIE會影響速度,對一些圖片等資源來講徹底時浪費帶寬;二來COOKIE只能存儲4K的數據,加密處理後能存放的更小。
種種的不肯定因素將產生各類奇怪的問題,避免過多的糾結,果斷改用其餘方式吧。
--EOF--除非註明,博客文章均爲原創,轉載請以連接形式標明本文地址本文地址: http://pengbotao.cn/codeigniter-session.html