1. 程式人生 > >PHP學習練手(十四)

PHP學習練手(十四)

SESSION會話

會話(session)

會話假定資料儲存在伺服器上,而不是瀏覽器中,會話識別符號用於定位特定使用者的記錄(會話資料)。這個會話識別符號通常通過cookie儲存在使用者的瀏覽器中,但是,敏感資料本身(如使用者ID,姓名等)總是保留在伺服器上。

會話與cookie的優缺點:

會話優點:
1. 一般更安全(因為資料儲存在伺服器上)
2. 允許儲存更多資料
3. 使用會話時,可以不使用cookie

cookie優點:
1. 更容易程式設計
2. 需要更少的伺服器資源
3. 通常情況下能夠持續更長時間

設定會話:
1、在使用它們的每個頁面都必須首先呼叫session_start()函式。這個函式告訴PHP開啟一個新會話,或者訪問一個現有的會話。必須在把任何內容傳送到Web瀏覽器之前呼叫這個函式。

2、第一次使用session_start()函式時,它會試圖傳送一個cookie,名稱為PHPSESSID(會話名稱)和一個ID值(32個16進位制字母)。由於試圖傳送一個cookie,所以在把任何資料傳送到web瀏覽器之前,就必須先呼叫這個session_start()函式。

開啟會話:
1、login.php 替換掉setcookie()相關:

。。。
//setcookie('user_id'
, $data['user_id'], time()+30, '/', '', 0, 0); //setcookie('first_name', $data['first_name'],time()+30, '/', '', 0, 0); session_start(); //echo session_id(); $_SESSION['user_id'] = $data['user_id']; $_SESSION['first_name'] = $data['first_name']; 。。。

注:
1、在php.ini中將session_auto_start設定為1,從而不必在每個頁面上使用session_start()。但缺點是加大伺服器開銷。

2、可以在會話中儲存陣列。

訪問會話變數:
1、loggedin.php修改$_COOKIE相關

session_start();
    //if(!isset($_COOKIE['user_id']))
    if(!isset($_SESSION['user_id']))
。。。
。。。
/*echo "<h1>Logged In</h1>
                    <p>You are now logged in, {$_COOKIE['first_name']}</p>
                    <p><a href=\"logout.php\">Logout</a></p>";*/

    echo "<h1>Logged In</h1>
                    <p>You are now logged in, {$_SESSION['first_name']}</p>
                    <p><a href=\"logout.php\">Logout</a></p>";

2、header.html修改$_COOKIE相關

/*if((isset($_COOKIE['user_id'])) && (basename($_SERVER['PHP_SELF']) != 'logout.php'))*/
                    if(isset($_SESSION['user_id']))

注:
1、session_start()函式允許當前指令碼訪問以前啟動的會話(如果它可以讀取cookie中儲存的PHPSESSID值)或者建立一個新的會話(如果它不能讀取這個值)。當找不到當前會話ID或者生成了新的會話ID,那麼舊會話ID下儲存的所有資料都將可不用

會話的垃圾收集

——是指刪除會話檔案(其中儲存了實際的資料)的過程。建立一個銷燬會話的登出系統是理想的,但是,並不能保證所有使用者都按應該做的那樣正式登出。所以PHP包含了一個清理程序。
無論何時呼叫session_start(), 都會引入PHP的垃圾分類集。用於檢查每個會話最近的修改日期(每當設定或獲取變數時都會修改會話)。有2個設定規定了垃圾收集:session_gc_maxlifetime和session.gc_probability。第一個設定用於指定在一個會話持續多少秒不活動之後,可將其看作空閒會話,從而刪除。第二個設定確定執行垃圾收集的概率,其取值範圍是1~100。預設設定是對每個session_start()都有1%的機會呼叫垃圾收集。如果PHP沒有啟動清理程序,則會刪除任何超過1440秒未使用的會話。

刪除會話變數:
1、單獨刪除一個會話變數:unset($_SESSION['var'])

2、刪除每個會話變數$_SESSION = array()

3、從伺服器中刪除所有的會話資料session_destroy()

4、logout.php修改

//setcookie('user_id', '', time()-3600, '/', '', 0, 0);
//setcookie('first_name', '', time()-3600, '/', '', 0, 0);
$_SESSION = array();   //刪除所有的會話變數
session_destroy();      //刪除會話
//刪除由session_start()建立的cookie
setcookie('PHPSESSID', '', time()-3600, '/', '', 0, 0);
。。。
。。。
/*echo "<h1>Logged Out!</h1>
                <p>You are now logged out, {$_COOKIE['first_name']}!</p>";*/

echo "<h1>Logged Out!</h1>
    p>You are now logged out!</p>";

注:刪除會話的所有痕跡:

第一步:刪除所有會話變數:$_SESSION = array();
第二步:刪除會話:session_destroy();
第三步:刪除會話建立的cookie:setcookie(‘PHPSESSID’, ”, time()-3600, ‘/’, ”, 0, 0);

提高會話安全性:

會話劫持(sessionhijacking):(舉例說明)如果我可以獲悉另一個使用者的會話ID,就可以輕鬆的欺騙伺服器把它看做是我的會話ID。此時,我就有效地接管了原使用者的整個會話,並且可以訪問他們的資料。

防止劫持:
方法一:在會話中儲存某種使用者識別符號,然後反覆地複查這個值,HTTP_USER_AGENT(所用的瀏覽器和作業系統的組合)是針對此目的的一個可能選擇。這會增加一層安全性,因為僅當我執行的瀏覽器和作業系統與另一位使用者完全一致時,才能夠劫持他的會話。$_SESSION['agent'] = md5( $_SERVER['HTTP_USER_AGENT'])

會話固定(會話攻擊的一種):
一個不懷好意的使用者指定了一個使用者的會話ID,則該使用者以這個固定的會話ID進入站點,並做任何事。然後,那個不懷好意的使用者可以訪問那個會話,因為他知道會話ID是什麼。使用者登入後通過更改會話ID來幫助防止這些型別的攻擊。session_regenerate_id()正是用於執行該任務的,它提供一個新的會話ID來引用當前的會話資料。