2012-05-12 76 views
8

我目前在我的網站上爲每個頁面提供了以下代碼。請任何人都可以確認這是否是開始並繼續PHP會話的好習慣?快速高效的PHP會話

//************************************************************ 
//Session Settings 
//************************************************************ 

$session_name = 'PHPSESSID'; 
$session_exp_time = 10000; 

$previous_name = session_name($session_name); 

//Set garbage collection parameters 
ini_set('session.gc_maxlifetime', $session_exp_time); 
ini_set('session.gc_probability', '1'); 
ini_set('session.gc_divisor', '100'); 

ini_set('session.name', $session_name); 
ini_set('session.cookie_domain', ''); //Session set to not be available to subdomains 
ini_set('session.cookie_lifetime', 0); 

//Set the session cookie parameters 
session_set_cookie_params($session_exp_time, '/', ''); 

//Start or continue a session... 
@session_start(); 

if (isset($_COOKIE[$session_name])) 
setcookie($session_name, $_COOKIE[$session_name], 2147483647, ''); 

請注意,該腳本包含在每個頁面中。

另一個相關的問題:

我應該設置一個自定義會話保存路徑,或者我應該只使用服務器的默認會話保存路徑?優缺點都有什麼?據我所知,如果您沒有設置自定義會話保存路徑,那麼您可能會在共享主機上發生某種衝突?請幫助指教。

在此先感謝!

+1

你有權訪問服務器的php.ini嗎?還是它支持.htaccess文件?如果是這樣,那些ini條目中的許多可以去。 –

+1

你也可以將它推入一個包含的php文件,所以你每次只包含文件而不是每次都包含所有的代碼。除非你已經這樣做了。並像@Jack說的PHP。ini或htaccess是您可以添加該代碼的其他地方。但是,如果您只是將其推入自己的PHP文件並在每個頁面上包含一次,那麼這也是一種很好的做法,您可以在1個文件中進行1次更改,並在引用該文件的任何位置自動更新。 – Danny

回答

5

您的許多陳述涉及會話配置設置;這些通常可以在服務器的php.ini或頂層.htaccess(Apache)中移動。

session.name = PHPSESSID 
session.gc_maxlifetime = 10000 

session.gc_probability = 1 
session.gc_divisor = 1000 

session.cookie_domain = 
session.cookie_path =/
session.cookie_httponly = 1 
session.cookie_lifetime = 0 

只要你這樣做,你不應該讓會話持續上去(2038年到期);會話通常會使用會話cookie(在技術上持續到瀏覽器關閉)持續。如果你想實現一個「記住我」功能,我建議你添加您的會議之上,喜歡這裏解釋:http://jaspan.com/improved_persistent_login_cookie_best_practice

我覺得很重要的是要開始一個新的會話和恢復現有的區別,尤其是在會議僅作爲登錄過程的一部分創建的情況下。當會話無法恢復時,出現問題,用戶應該重定向回登錄頁面(或主頁)。

PHP不明白區別,session_start會自動創建一個會話,如果它不存在,更糟的是,如果給定任意會話ID;後者允許會話採用攻擊,如下所示:http://gihyo.jp/dev/serial/01/php-security/0025 - 它是日文版,您必須使用瀏覽器翻譯它。

要確定會話是否可以恢復,您需要通過添加一個特殊的密鑰來填充每個新會話(例如$_SESSION['_id'] = session_id())。如果找到該密鑰,則該會話已存在,您可以繼續;如果沒有,該會話要麼不存在,要麼有人試圖向您提供錯誤的ID。

要開始一個新的會話,你首先看看它是否可以恢復;如果不是,則使用session_regenerate_id(true)更改會話ID(這會使攻擊者劫持會話變得更困難)。

最後,共享服務器上的會話保存路徑可以寫在您自己的主文件夾下,但這隻有在共享主機與每個虛擬主機的專用用戶(即suexec)一起運行時纔有意義。否則,爲了保護您的會話免受窺探攻擊,您必須對會話數據(也可能是密鑰)進行編碼。查看mcrypt擴展:http://sg.php.net/mcrypt - 您應該可以在線查找示例。

我希望這或多或少地回答你的問題。如果您認爲有什麼不妥之處,請告訴我。

+0

謝謝你抽出時間幫忙,傑克。非常感謝。我無法知道會話是否可以恢復。我嘗試使用:if(session_id()=='')來查看會話是否已啓動,但它總是返回TRUE,即使會話已經啓動? –

+0

您可以隨時調用session_start(),然後檢查該會話中的密鑰,如isset($ _ SESSION ['_ started']) –