编辑:在投诉给自己分配答案之后,我想更新所提供的答案并不令人满意。没有人出来并明确表示这是你的问题,做到这一点,你将有一个决议。仅仅建议不足以获得赏金奖励。最后,问题出在服务器设置上,在对服务器会话进行一些研究并查看Stackoverflow / Serverfault后,我能够确定如何最好地解决这个问题。因此,我认为将自己的答案标记为正确答案并不公正。
我有一个基于php的身份验证系统,它依赖于LDAP来验证身份并使用会话来维护用户身份验证状态。
最近我注意到它似乎正在把我推回登录页面,就像我的会话过期一样。问题是,它似乎没有任何特定的原因,我已经注意到,我不知道如何调试/测试这样的东西。
这是我启动会话的身份验证功能:
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 :(得分:2)
您似乎混淆了身份验证,授权和会话管理。如果你想测试所有3,那么你需要某种自动测试工具,能够进行脚本化,有状态的HTTP会话重放(例如http :: recorder / www :: mechaninze with Perl)。
OTOH如果您想使用已部署的应用程序调查会话管理,那么我建议使用登录页面来捕获有关当前会话以及用户如何路由的信息。您还应该考虑在Web服务器上记录会话cookie。
答案 1 :(得分:2)
目前还不确定您使用的是哪种测试软件,但我强烈推荐Selenium。它允许您通过浏览器运行脚本测试,有效地模拟最终用户将要执行和查看的内容。
答案 2 :(得分:1)
编写功能测试。你可以使用SimpleTest的WebTestCase来做这样的事情。请参阅以下文档:http://www.simpletest.org/en/web_tester_documentation.html
当然,您也可以尝试将代码分解为更小的位,以便更容易单独测试。现在,您的身份验证系统与服务器状态紧密耦合(例如,会话管理)。您可以将两者分离,从而能够在单元测试中测试身份验证系统,而不是功能测试。
答案 3 :(得分:0)
服务器可能会覆盖他们的会话cookie,这会改变会话哈希,然后它将不会与他们拥有客户端的cookie相等。你似乎在思考这个问题。您无需在其系统上设置cookie来验证它们。 $ _SESSION var将为您处理所有这些。
如果他们通过了挑战,那么他们就会设置一个$ _SESSION var来为他们提供auth级别。
不要将$ _SESSION传递给其他类似的vars。不要去$ username = $ _SESSION ['username'],因为现在你有一个非安全的var($ username)可以保护数据。但它可能不会。
每当您显示会话信息时,请确保它来自马的嘴。
答案 4 :(得分:0)
我会(如果你不愿意考虑你的概念)改变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()
您确定在session_start()
isValidUser()
吗?
答案 5 :(得分:-1)
这似乎是服务器本身的简单错误配置。由于这个服务器环境是数百个站点的共享环境,我无法在php.ini等中修改服务器范围的设置。
我能做的是......
session_set_cookie_params(time()+$expiration, $path, $domain, true, true);
这已解决了问题,它在会话到期之前未正确设置,并且会针对此特定应用程序进行相应设置。