ホームページ >バックエンド開発 >PHPチュートリアル >**MySQL ログイン スクリプトが機能しないのはなぜですか?**

**MySQL ログイン スクリプトが機能しないのはなぜですか?**

Susan Sarandon
Susan Sarandonオリジナル
2024-10-26 07:15:021048ブラウズ

**Why is my MySQL login script not working?**

ログイン スクリプトの MySQL 接続に関する問題は何ですか?

提供されたコード フラグメントには、問題が発生している領域がいくつかあるようです。ログインフォームで問題が発生している可能性があります。一つずつ見ていきましょう:

1.データベース接続:

PHP ファイルlogin.php で、次のコードを使用してデータベースへの接続を確立しようとします:

<code class="php">// Pretend the following is locked in a vault and loaded but hard coded here
$hostname = "localhost";
$database = "boost";
$username = "root";
$password = "";
$localhost = mysqli_connect($hostname, $username, $password, $database);

if (mysqli_connect_errno()) {
    die("Connection Failed" . mysqli_error());
}</code>

ただし、ハードコーディングされています。データベースの認証情報。これらの詳細は将来変更される可能性があるため、コード内にこれらの詳細をハードコーディングすることはお勧めできません。代わりに、セキュリティと柔軟性を高めるために、構成ファイル内のデータベース認証情報を分離し、そこから読み取ることをお勧めします。

2.準備されたステートメント:

register.php とlogin.php の両方で、mysqli_prepare 関数を使用して SQL ステートメントを準備します。ただし、後で mysqli_stmt_execute を使用してそれらを実行することはありません。これにより、クエリが実行されなくなり、ログインまたは登録が失敗します。

3.バインドパラメータ:

mysqli_stmt_bind_param 関数を使用する場合は、バインドされたパラメータのタイプを指定する必要があります。 register.php と login.php の両方で、文字列用の「s」タイプを使用してパラメータをバインドします。ただし、整数値をバインドする場合は、整数の場合は「i」など、適切な型指定子を使用する必要があります。

4.ユーザー認証:

login.php では、ユーザーのパスワードを検証するときに、クリアテキストのパスワード ($ctPassword) をデータベースに保存されているハッシュされたパスワード ($dbHashedPassword) と直接比較します。攻撃者がリクエストを傍受できれば、ユーザーのパスワードにアクセスできるようになるため、これはセキュリティ上のリスクです。代わりに、password_verify 関数を使用して、ハッシュされたパスワードを安全に比較する必要があります。

5.セッション処理:

ログイン成功時にユーザーの ID を保存するには、$_SESSION スーパーグローバルを使用します。ただし、login.php の session_start() を使用してセッションを開始することはありません。これにより、セッションが適切に初期化されなくなり、セッション データが利用できなくなります。

6. SQL インジェクション:

SQL クエリの実行時にプリペアド ステートメントを使用していないため、コードが SQL インジェクション攻撃に対して脆弱になります。このタイプの攻撃を防ぐには、常にプリペアド ステートメントを使用する必要があります。

これらの問題に対処する更新されたコードの一部を次に示します。

register.php:

<code class="php">session_start();

if (isset($_POST['register'])) {
    $email = $_POST['email'];
    $ctPassword = $_POST['password'];   // Cleartext password from user

    // Pretend the following is locked in a vault and loaded but hard coded here
    $host = "yourhostname";
    $dbname = "dbname";
    $user = "dbuser";
    $pwd = "password";
    $port = 3306; // Comes along for the ride so I don't need to look up param order below

    try {
        $mysqli = new mysqli($host, $user, $pwd, $dbname, $port);

        if ($mysqli->connect_error) {
            die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
        }

        $query = "INSERT INTO user_accounts2(email, password) VALUES (?, ?)";
        $stmt = $mysqli->prepare($query);

        $hp = password_hash($ctPassword, PASSWORD_DEFAULT); // Hashed password using cleartext one

        $stmt->bind_param("ss", $email, $hp);
        $stmt->execute();

        $iLastInsertId = $mysqli->insert_id;
        $stmt->close();
        $mysqli->close();
    } catch (mysqli_sql_exception $e) {
        throw $e;
    }
}</code>

login.php:

<code class="php">session_start();

if (isset($_POST['login'])) {
    $email = $_POST['email'];
    $ctPassword = $_POST['password'];   // Cleartext password from user

    // Pretend the following is locked in a vault and loaded but hard coded here
    $host = "yourhostname";
    $dbname = "dbname";
    $user = "dbuser";
    $pwd = "password";
    $port = 3306;

    try {
        $mysqli = new mysqli($host, $user, $pwd, $dbname, $port);

        if ($mysqli->connect_error) {
            die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
        }

        $query = "SELECT id, email, password FROM user_accounts2 WHERE email = ?";
        $stmt = $mysqli->prepare($query);

        $stmt->bind_param("s", $email);
        $stmt->execute();

        $result = $stmt->get_result();

        if ($row = $result->fetch_array(MYSQLI_ASSOC)) {
            $dbHashedPassword = $row['password'];
            if (password_verify($ctPassword, $dbHashedPassword)) {
                echo "Right, userId=";
                $_SESSION['userid'] = $row['id'];
                echo $_SESSION['userid'];
            } else {
                echo "Wrong";
            }
        } else {
            echo 'No such record';
        }

        $stmt->close();
        $mysqli->close();
    } catch (mysqli_sql_exception $e) {
        throw $e;
    }
}</code>

追加メモ:

  • データベースのやり取りを簡素化するために、PDO や Doctrine などのデータベース抽象化レイヤー (DAL) を使用することを強くお勧めします。
  • パスワードを平文でデータベースに保存しないでください。 bcrypt や Argon2 などの強力なハッシュ アルゴリズムを使用して、常に安全にハッシュしてください。
  • プリペアド ステートメントを使用して、SQL インジェクション攻撃を防ぎます。
  • 悪意のある攻撃を防ぐために、データベースに送信する前にユーザー入力を検証します。
  • アプリケーションをさまざまな種類の攻撃から保護するために、より堅牢なセキュリティ フレームワークの使用を検討してください。

以上が**MySQL ログイン スクリプトが機能しないのはなぜですか?**の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。