為網站自訂個別的php session path

這幾天跟外校的資訊組長聊天的時候,聊起早些年經費拮据的運作方式

當然免不了的現象就是沒有像樣的空間當機房、PC抓來就開服務當SERVER

總之有各種奇奇怪怪的回憶,也是很有趣

但是到了這幾年情況有些不太相同了

因為SERVER硬體設備的採購成本不再那麼高不可攀、網路基礎建設的概念推廣開來

所以慢慢的,多數學校至少都有PC SERVER可以使用、網路結構也開始改善

更有不少學校開始採購機架式的伺服器投入服務

於是,早期服務分散(不把雞蛋放在同一個籃子裡)的觀念,慢慢的改為服務整併的過程

採購一兩台還不錯的標準機架式伺服器,其效能抵過一整櫃的PC SERVER也不誇張

然而,整併的過程當然比起每台機器很單純的跑特定服務的情況複雜一點

前陣子有寫過一篇筆記就是個例子 (詳見:register_global 設定)

為什麼會突然又提起這個呢?

其實是因為正好今天在改一點SERVER設定的時候想到,應該做個筆記

就是有關於「為同一台SERVER上不同網站服務設定個別的Session Path」

因為服務整併,所以一台機器上面透過Apache VirtualHost的設定

同時跑上好多個網站是很普遍的做法,甚至有些人可能連VirtualHost都懶得做

直接就一台SERVER的不同目錄就跑不同的網站服務

其實這樣的做法不會有什麼問題的,就算所需要的php運作環境不同

也還可以透過自訂 .htaccess 複寫目錄的php設定

特別是如果都是使用架站套件,大概永遠也不會遇上我接下來提到的狀況

Session變數被跨網站存取了!

通常這比較容易發生在自己寫作程式的網站上

舉個例子來說: http://aa.bb.cc/siteA http://aa.bb.cc/siteB

這兩個網站同時存在一台機器上,只是放在不同的目錄罷了

撰寫程式的時候,大概免不了會使用到 SESSION 來傳遞一些變數

偏偏人總是會有習慣性與惰性的

有時候我們總是會習慣用同樣的變數名稱來代表同樣的內容

例如寫了個登入程式,驗證成功之後我們來寫兩個變數

$_SESSION['user']、$_SESSION['level']

分別代表使用者帳號、使用者權限等級,到這裡都沒有什麼問題

但是如果SiteA與SiteB這兩個不同的網站

卻在同一台機器上使用同樣方法來紀錄登入者

那麼,應該會很神奇的發現,只要在http://aa.bb.cc/siteA網站登入

http://aa.bb.cc/siteB 也會因為判斷到 $_SESSION['user']、$_SESSION['level'] 的存在

讓B網站也誤以為你是個以經登入的使用者

通常不同的網站,就算是相同的人開發,也不見得一般使用者名稱會相同

不過...如果是管理者呢?哈~總是逃脫不了那些常見的帳號啦 @@

這是指「習慣性」造成的問題,那「惰性」呢?

恩...copy先前開發的程式直接換個路徑、Database就開始運作的,應該也不少人吧

其實,同一台SERVER跑不同的網站服務

就算使用相同的SESSION NAME也是可以讓他安全一點點的

關鍵就在於SESSION PATH這個部分

大家都知道php的session路徑就是在php.ini當中設定,預設是存成獨立檔案

但是,同一台機器上面的不同網站如果都是使用預設的路徑去存取session

當然很容易造成不同網站session互通有無,相對就比較困擾、也比較不安全 @@

所以,同樣利用前面提到的 .htaccess 複寫 php.ini 設定,多少買一點保險

同樣用前述的 SiteA 、 SiteB 來當例子好了

Step 1 》修改 httpd.conf 允許複寫設定

<Directory "/var/www/html/SiteA" >

Options Indexes FollowSymLinks

AllowOverride All

Order allow,deny

Allow from all

</Directory>

<Directory "/var/www/html/SiteB" >

Options Indexes FollowSymLinks

AllowOverride All

Order allow,deny

Allow from all

</Directory>

Step 2 》建立複寫設定

分別在 SiteA、SiteB 的目錄中產生一個 .htaccess

Step 3 》各自設定Session Path

例如分別在各自的 .htaccess 中寫入

php_value session.save_path "/某個路徑/SiteA_session"

php_value session.save_path "/某個路徑/SiteB_session"

Step 4 》 重新啟動Apache

/etc/rc.d/init.d/httpd restart

就這樣簡單。

經過三個步驟的修改,SiteA與SiteB如果遇到程式要求註冊Session的時候

會分別寫在不同的路徑,這樣就算是相同的Session Name也不會在兩個網站互通有無了

而同一台機器上的其他網站,如果沒有去變更設定的話

還是會繼續把session檔案存在php.ini預設的路徑 (/var/lib/php/session/)當中

只是,看manual說,如果自訂php session path的話,好像就要手動去清session file

其實也沒關係啦,到 crontab 去加個指令,每隔一點時間把所有session全清了就是

雖然早就做過類似的設定,不過好像也沒把筆記寫下來過

今兒個心血來潮,做個筆記好了 XD

留言