2010-09-14 54 views
0

編輯:在投訴了自己的答案後,我想更新提供的答案並不令人滿意。沒有人出來,並明確表示這是你的問題,這樣做,你會有一個解決方案。僅僅建議不足以獲得賞金獎勵。最後,問題出在服務器設置上,在對服務器會話進行一些研究後,看着Stackoverflow/Serverfault,我能夠確定如何最好地解決這個問題。因此,我認爲將自己的答案標記爲正確答案並不公平。如何測試認證系統?

我有依靠LDAP驗證身份並使用會話保持用戶認證狀態基於PHP的身份認證系統。

最近我注意到,它似乎把我推回到登錄頁面就像我的會話過期。問題是,它似乎沒有任何特定的原因,我已經注意到,我不知道如何調試/測試這樣的事情。

這裏是我的身份驗證功能,啓動會話:

function authenticateUser($user, $password){ 
    //assuming ldap connection and verification of user login/pass 
    //this is what will happen with authenticate user which is called 
    //when user submits login/pass on authentication form. 
    $_SESSION['id'] = $uID; 
    $time = time(); 
    $_SESSION['time'] = $time;         
    $_SESSION['lastActivity'] = $time; 
    $_SESSION['expiration'] = $time+$cookieExpiration; 
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR']; 
    $_SESSION['secret'] = md5(rand());       
    $_SESSION['userHash'] = getSessionHash(); 
    $_SESSION['firstLogin'] = isFirstLogin($user); 
    //assign cookie to user and log authentication 
    giveCookie("userHash", $_SESSION['userHash'],0); 
    logAuthenticationAttempt($user, $_SERVER['REMOTE_ADDR'], 1); 
    return true; 
}//end authenticateUser 

給cookie的功能:

function giveCookie($name, $value, $expiration=0){ 
    global $path, $site; 
    setcookie("userHash", $_SESSION['userHash'], $expiration, $path, $site, true, true);  
}//end giveCookie 

這裏是我的函數被稱爲每一頁上驗證用戶才讓通過認證他們繼續採取需要認證狀態的行動:

function isValidUser(){ 
    global $links; global $userName; global $userID; global $cookieExpiration; 
    if(isset($_COOKIE['userHash']) and isset($_SESSION['userHash'])){ 
     if($_COOKIE['userHash'] == $_SESSION['userHash']){ 

     $userName = $_SESSION['nameN']; 
     $userID = $_SESSION['id']; 
     //update userHash cookie for additinoal expiration time this way session 
     $time = time(); 
     $expiration = $time+$cookieExpiration; 
     $_SESSION['lastActivity'] = $time; 
     giveCookie("userHash", $_SESSION['userHash'],0); 
     $_SESSION['expiration'] = $expiration; 
     return true; 
     } 
    } 
    return false; 
}//end isvalidUser() 

任何意見或反饋如何測試這將不勝感激。我正在尋找找出爲什麼偶爾執行一些操作後,我被推回到登錄頁面。

在其請求驗證了我在上面做一個頁面如下:

if(!isValidUser()){changePage($links['login']."?refer=".$links['requestHelp']);} 
//note: changePage is just a function for header("location: somepage.php"); 
+0

如果你不能單元測試代碼,也許它沒有任何單位。將你的代碼分成更小,邏輯上相關的部分。 – erenon 2010-09-14 12:35:52

+0

那些2個在邏輯上是一致的,據我所知,驗證用戶大是因爲它必須檢查LDAP連接失敗,綁定,搜索,並再次結合。否則,這兩個功能只能執行小任務。 – Chris 2010-09-14 12:37:48

+0

我個人認爲你需要快速學習面向對象編程。 – RobertPitt 2010-09-14 12:41:33

回答

2

你似乎是混亂的認證,授權和會話管理。如果你想測試所有3,那麼你需要一些能夠腳本化,有狀態的HTTP會話重播的自動化測試工具(例如http :: recorder :: www :: mechaninze with Perl)。

,如果你想用你部署的應用程序來調查會話管理OTOH,那麼我建議你插裝在登錄頁面,以獲取有關當前會話和用戶如何得到路由有信息。您還應該考慮在Web服務器上記錄會話Cookie。

+0

你能提供一些關於如何測試這些的細節嗎? – Chris 2010-09-14 12:57:22

+0

這是哪位? – symcbean 2010-09-14 15:29:31

0

服務器可能改寫他們的會話cookie,這將改變會話哈希,然後將不等於他們有客戶方的餅乾。你似乎在推翻這一點。你不需要在他們的系統上設置一個cookie來驗證它們。 $ _SESSION var將爲您處理這一切。

如果他們通過挑戰,那麼他們有一個設置,讓他們AUTH水平的$ _SESSION變種。

不要將$ _SESSION傳遞給像你這樣的其他變量。不要去$ username = $ _SESSION ['username'],因爲現在你有一個不安全的變量($ username),它可以保護其中的數據。但它可能不會。

每當你顯示會話信息,請確保它來自馬的嘴。

+0

所以僅僅依靠$ _SESSION [「用戶名」]當我需要它,不要將此值使用以後設置爲一個變量?雖然不是完全回答我原來的問題,但如果這是一個好的做法,我會執行它。 – Chris 2010-09-20 14:52:49

+0

你也不需要userhash檢查。這是你問題的根源。 userhash cookie不與服務器會話變量同步。當會話超時時,代碼將不允許它通過。 – Geekster 2010-09-20 14:56:42

+0

那麼userhash檢查與會話超時有什麼關係?你從來沒有解釋過這一點,因此你從來沒有收到過這個問題或賞金的答案。順便說一下,答案是他們不這樣做。 – Chris 2010-09-23 10:11:12

0

採取在session.configuration

一個深沉的樣子我會(如果你不願意去思考過你的概念)改變isValidUser登錄,你可以得到什麼以前return false

function isValidUser(){ 
    global $cookieExpiration; // since $links isn't used and $userName and $userId come from $_SESSION no need for global there 
    if((isset($_COOKIE['userHash']) and isset($_SESSION['userHash'])) 
     and ($_COOKIE['userHash'] == $_SESSION['userHash'])){ 

     $userName = $_SESSION['nameN']; // why these lines? 
     $userID = $_SESSION['id']; // see above 
     //update userHash cookie for additinoal expiration time this way session 
     $time = time(); 
     $expiration = $time+$cookieExpiration; 
     $_SESSION['lastActivity'] = $time; 
     giveCookie("userHash", $_SESSION['userHash'],0); 
     $_SESSION['expiration'] = $expiration; 
     return true; 
    } 
    // $logger ist just an example an could be a p.e Zend_Logger Object 
    $logger->debug($_SESSION); // serialize if needed 
    $logger->debug($_COOKIE); // serialize if needed 
    $logger->err(error_get_last()); 
    return false; 
}//end isvalidUser() 

而且你確定你以前isValidUser()

1

寫一個功能測試稱爲session_start()。你可以使用SimpleTest的WebTestCase這樣的東西。請參閱以下文檔:http://www.simpletest.org/en/web_tester_documentation.html

當然,您還可以嘗試將代碼分解爲更小的代碼,這些代碼可以更容易地單獨進行測試。目前,您的身份驗證系統與服務器狀態緊密相關(例如會話管理)。您可以將兩者解耦,從而能夠在單元測試中測試認證系統,而不是進行功能測試。

+0

您可以詳細解釋一下如何分離身份驗證和服務器狀態嗎?我明白什麼分離手段,但不確定在這種情況下,如何分離認證從服務器會話。 – Chris 2010-09-20 14:54:08

+0

基本上,通過封裝更改會話/ cookie的所有內容。然後,您可以將其嘲笑,同時獨立測試其餘的邏輯。您仍然需要編寫Web測試用例來測試會話/ Cookie代碼,但是您會在每個組件中保持複雜性。另外,您可以爲多個組件重用會話/ Cookie代碼,每個組件都可以搭載相同的測試。 – troelskn 2010-09-21 09:27:54

+0

..如果你採用這種方法,你很可能很容易就能確定問題出在會話管理(以及服務器配置)上,而不是你的身份驗證邏輯。當然,我只是第二次在這裏猜測你 - 得出你自己的結論;) – troelskn 2010-09-21 09:30:27

2

不知道你用什麼測試軟件的時刻,但我強烈建議Selenium。它允許你通過瀏覽器運行腳本化測試,有效地模擬最終用戶會做什麼和看到什麼。

-1

看來,這是服務器本身的簡單配置錯誤。由於該服務器環境是數百個站點的共享環境,因此我無法修改php.ini等中的服務器範圍設置。

我能夠做的,雖然是什麼...

session_set_cookie_params(time()+$expiration, $path, $domain, true, true); 

這已經解決了這個問題,它出現之前正確未設置會話到期,這將相應地設置它爲這個特定的應用程序。

+0

等一下。你應該代表100分,因爲我告訴你問題在於你的用戶cookie和會話限制不同步,你似乎已經通過你的代碼修復了這個問題。我可能會補充說,如果用戶關閉瀏覽器時舊cookie仍然存在,那麼您的代碼似乎仍然存在問題,即用戶的Cookie可能會與會話不同步。所以依靠他們的cookies可能不是一個好主意。再加上這是一種糟糕的形式+代表你自己的答案。 Serverside會話是要走的路。 – Geekster 2010-09-20 16:00:05

+0

1.我對自己的答案沒有任何聲譽。 2.你的回答沒有解決問題。代碼不會覆蓋會話,並且cookie被設置爲驗證會話,因爲userHash是一些變量的散列,它提供了一種驗證用戶的方式,即他們說他們是誰。 3.當用戶嘗試進行身份驗證時,登錄會清除userHash cookie,因此如果用戶轉到要求身份驗證的頁面,並且userHash不匹配,那麼他們將被強制重新登錄。 4.如果有什麼maggie的回答比你自己的回答好。 – Chris 2010-09-20 16:16:43

+0

最後,在獎勵他們之前,我失去了獎勵的點數,所以即使我獎勵了自己的賞金,我也不會獲得獎勵,我會重新獲得最初獎勵獎勵的點數,而不是獲得額外積分。賞金是當你放棄點數而不是創造額外點數的時候。 – Chris 2010-09-20 16:19:08