在实习期间,我正在进行一个非常好的教程,为购物车制作高级PHP安全会话,这将为用户提供个人级别的定价(无论如何这都是目标。)
这是教程: http://tutorial-resource.com/2011/10/a-secure-session-management-class-in-php/
首先,我创建了一个原始登录,根据Quickbooks客户ID检查现有客户,以便测试此会话。真正的处理使用注册,登录和密码。然后我做了一个登录检查器,在mysql数据库中找到用户,找到后,检索需要与用户逐页保持一致的用户数据列。 (我承诺,在我开始工作之后,我将进一步阻止SQL注入。)我添加了一些额外的字段以存储在SessionData中。
<?php
include "class.session.php";
if(empty($_POST['customer_id']))
{
$this->HandleError("Customer ID is empty!");
return false;
}
$customer_id = trim($_POST['customer_id']);
$dbuser = "CENSORED";
$dbpass = "CENSORED";
$host = "localhost";
$dbname = "CENSORED";
// database connection
mysql_connect("localhost", $dbuser, $dbpass) or die(mysql_error());
mysql_select_db($dbname) or die("Unable to select database");
//This query grabs all the puchases going back up to three months
//This debug line displays the query
$query = "SELECT * FROM customers";
echo $query."<br>";
$found = 0;
$result = mysql_query($query);
while($row=mysql_fetch_array($result))
{
//Grab the database pieces the customer will need throughout the page.
echo "Checking customer number ".$row['customer_id']."<br>";
if ($row['customer_id'] == $customer_id)
{
$found = 1;
break;
}
}
//-create while loop and loop through result set
if ($found == 0)
{
echo 'Wrong customer number';
}
while($row=mysql_fetch_array($result))
{
//Grab the database pieces the customer will need throughout the page.
$customer_id = $row['customer_id'];
$first_name = $row['first_name'];
$last_name = $row['last_name'];
$first_name = $row['price_level'];
}
//Give the user a session.
$sessions = new sessionsClass;
$sessions->_sessionStart();
$sessionInfo = $sessions->sessionCheck();
if( $sessionInfo = false )
{
# This session is invalid. Tell the user.
}
else
{
# Update the name.
$sessionInfo->sessionData['customer_id'] = $customer_id;
$sessionInfo->sessionData['company_name'] = $company_name;
$sessionInfo->sessionData['first_name'] = $first_name;
$sessionInfo->sessionData['last_name'] = $last_name;
$sessionInfo->sessionData['price_level'] = $price_level;
$sessionInfo->setSessionData();
# Session is valid, can use the data.
echo "Your name is ".$sessionInfo->sessionData['first_name']." ".$sessionInfo->sessionData['last_name']."<br>";
}
?>
成功登录后,我在error_log中看到一条错误 “在明确函数存在时,直接从教程中调用关于此行的未定义方法stdClass :: setSessionData()”: $ sessionInfo-&GT; setSessionData();
为什么登录不会将setSessionData识别为未定义的方法而不是函数?
我不完全理解的一个线索是它将setSessionData称为“未定义的方法stdClass”而不是“未定义的函数”。该函数与教程非常相似,只是它连接到我的db:
public function setSessionData()
{
$dbuser = "CENSORED";
$dbpass = "CENSORED";
$host = "localhost";
$dbname = "CENSORED";
// database connection
mysql_connect("localhost", $dbuser, $dbpass) or die(mysql_error());
mysql_select_db($dbname) or die("Unable to select database");
//Encrypt the data.
$serialiseData = serialize( $this->sessionData );
//Update the session data.
mysql_query( "UPDATE sessions SET sessionData = '{$serialiseData}' WHERE sessionHash = '{$this->sessionHash}'" );
}
我的最后一个问题是,无论在哪个页面,每个页面都需要安全地区分普通用户和登录用户?是这样的吗?
if (sessionCheck == false)
{show ordinary stuff}
else if (sessionCheck == return true)
{show personalized stuff}
编辑本教程似乎有一些问题。例如,在教程结束时。
# Session is valid, can use the data.
echo "Your name is " . $sessionInfo->sessionData['fullname'];
# Update the name.
$sessionInfo->sessionData['fullname'] = "My New name";
$sessionInfo->setSessionData();
}
这是错误的,因为sessionInfo是一个布尔值,意味着为false返回true。相反,我用
替换了它$sessions->sessionData['customer_id'] = $customer_id;
$sessions->sessionData['company_name'] = $company_name;
$sessions->sessionData['first_name'] = $first_name;
$sessions->sessionData['last_name'] = $last_name;
$sessions->sessionData['price_level'] = $price_level;
$sessions->setSessionData();
但那仍然没有成功。此外,本教程还让人们创建了一个完整的MySQL数据库,但是没有一个INSERT发生在类或教程中的任何地方。 UPDATE查询已经存在的会话的功能就在那里,但没有用于创建新会话的功能。我可以添加什么来使数据库成功创建会话?
答案 0 :(得分:0)
如果在反序列化期间无法找到类,则序列化对象将转换为stdClass
。我的猜测是,当您从数据库中读取会话信息并尝试将其放回sessionClass
对象时,您尚未包含定义该类的文件。确保在反序列化之前定义了类。
由于stdClass
没有名为setSessionData
的方法,因此您会收到“调用未定义方法”错误。方法通常用于表示类中的函数,而函数只是一个独立的函数定义。
要在每个页面上区分普通用户的登录用户,通常需要启动会话并检查特定于应用程序的值,该值指示用户已通过身份验证。这可以像在会话中设置loggedIn
标志,或存储更复杂的类型并检查其值一样简单。但基本上你需要在登录用户中了解普通用户所需的每个页面上进行此操作。
希望有所帮助。
另外,如果您在代码的开头调用$this->HandleError("Customer ID is empty!");
,那么如果该块执行,您将收到错误消息,指出$this
未定义。由于该代码未在类中调用,因此没有$this
的实例,因此您必须找出处理该错误的正确方法。