1

だから私はphp認証スクリプトを持っていて、すべてがうまくいきます。しかし、私はそれをプログラムした方法(私はいくつかのものをハードコーディングした)について非常に確信がなく、スタックがこれを調べて潜在的な問題を指摘できることを望んでいました。

スクリプトは次のとおりです。

<?php
require_once 'Bcrypt.php';
class Mysql {
    private $conn;

    function __construct() {
        $this->conn =  new PDO('mysql:host=***;dbname=***;charset=UTF-8','***','***') or 
                      die('There was a problem connecting to the database.');
    }

    function verify_Username_and_Pass($un, $pwd) {
        ini_set('display_errors', 'On');
        error_reporting(E_ALL | E_STRICT);
        $query = "SELECT *
                FROM Conference
                WHERE Username = :un";

        $stmt = $this->conn->prepare($query);

        $stmt->bindParam(':un', $un);
        //$stmt->bindParam(':pwd', $pwd);
        $stmt->execute();
        $row = $stmt->fetchAll();
        $hash = $row[0]["Password"];
        $is_correct = Bcrypt::check($pwd, $hash);

        if ($is_correct) {
            // User exist
            $firstName = $row[0]["First Name"];
            $_SESSION["FirstName"] = $firstName;
            return true;
            $stmt->close();
        }
        else {
            // User doesn't exist
            return false;
            $stmt->close();
        }
    }
}
?>

それで、それはどのように見えますか?

4

2 に答える 2

1

テストしなくても、コードは機能するはずです。BCryptの使用法は妥当なようです。もちろん改善できる点もありますし、意見の問題かもしれません。

  1. クエリが行を返さない場合(そのようなユーザー名が存在しないため)、無効なインデックスにアクセスします$row[0]["Password"]。使用する前に、結果があるかどうかを最初に確認する必要があります。
  2. データベースを閉じるための呼び出しはreturnステートメントの後に配置されるため、実行されることはありません。PHPはデータベースを自動的に閉じるので、returnステートメントの前にデータベースを閉じるか、行を削除します。
  3. 関数verify_username_and_password()に名前を付けましたが、実際にはデータベースからの読み取りとセッションへの書き込みも行います。これらは隠されたアクティビティであり、別の開発者は、コード全体を読まない限り、セッションが変更されたことを知ることができません。この問題を解決する1つの可能性は、関数を分割することです。

テストされていない例:

$userRow = getUserRowFromDatabase($userName);
if (!is_null($userRow))
{
  if (verifyPassword($password, $userRow["Password"]))
  {
    addLoggedInUserToSession($userRow["First Name"])
  }
}

これら3つの機能のそれぞれには、解決すべき問題が1つだけあります。これにより、コードが読みやすくなります。理想的には、本の物語を読むようなものである必要があります。

私があなたにいくつかのアイデアを与えることができることを願っています。

于 2012-10-04T19:56:44.913 に答える
0

実際にmysqlを使用してハッシュを検証できます

 SELECT COUNT(*) FROM Conference
 WHERE Username = :un
 AND Password = ENCRYPT(:pass, Password)
 LIMIT 1
于 2012-10-04T19:04:50.797 に答える