1

インターンシップで、私はショッピング カート用の高度な 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>";
}

?>

ログインに成功した後、チュートリアルからそのまま抜け出して、明らかに関数が存在するのに、この行に関して「未定義メソッド stdClass::setSessionData() への呼び出し」というエラーが error_log に表示されます: $sessionInfo->setSessionData();

ログインがsetSessionDataを関数ではなく未定義のメソッドとして認識しないのはなぜですか?
私が完全に理解していない手がかりは、setSessionData を「未定義関数」ではなく「未定義メソッド stdClass」として参照していることです。この関数は、私のデータベースに接続することを除いて、チュートリアルと非常に似ています:

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}

EDIT このチュートリアルは結局、いくつかの問題を抱えているようです。たとえば、チュートリアルの終わり近く。

# 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 クエリの機能はありますが、新しいセッションを作成する機能はありません。データベースでセッションを正常に作成するには、何を追加できますか?

4

1 に答える 1

0

stdClass非シリアル化中にクラスが見つからない場合は、シリアル化されたオブジェクトに変換されます。私の推測では、データベースからセッション情報を読み取ってオブジェクトに戻そうとしたsessionClassときに、そのクラスを定義するファイルが含まれていなかったと思います。アンシリアライズする前に、クラスが定義されていることを確認してください。

stdClassと呼ばれるメソッドがないためsetSessionData、「未定義のメソッドへの呼び出し」エラーが発生します。メソッドは、クラス内の関数を参照するために一般的に使用される用語ですが、関数は単なるスタンドアロンの関数定義です。

各ページでログイン ユーザーと通常のユーザーを区別するには、通常、セッションを開始し、ユーザーが認証されていることを示すアプリケーション固有の値を確認する必要があります。loggedInこれは、セッションでフラグを設定したり、より複雑な型を格納してその値をチェックしたりするのと同じくらい簡単です。ただし、基本的には、ログインしているユーザーから通常のユーザーを知るために必要な各ページでそれを行う必要があります。

それが役立つことを願っています。

余談ですが$this->HandleError("Customer ID is empty!");、コードの先頭で呼び出している場合、そのブロックが実行されると、$thisが定義されていないというエラーが表示されます。そのコードはクラス内で呼び出されていないため、のインスタンスがない$thisため、そのエラーを処理する正しい方法を理解する必要があります。

于 2012-06-29T17:03:20.177 に答える