sql >> データベース >  >> RDS >> Mysql

ログインフォームを取得してmySQLデータベースと適切に相互作用することができません

    この回答はハッシュ用です。 password_hash() 、および password_verify() 。 mysqliとpdoの両方。下部のリンクには、さらにリンクがあり、塩などに関するいくつかの言語があります。

    選択と挿入でユーザー提供のデータを直接使用しないことが重要です。むしろ、パラメータをバインドし、プリペアドステートメントをに呼び出します。 SQLインジェクション攻撃を回避する 。パスワードは、データベースのクリア(クリアテキスト)に保存しないでください。むしろ、一方向のハッシュを介して送信する必要があります。

    また、注意してください。これは、登録ハッシュとログイン検証を示しています。 本格的ではありません 私がコードキャニオンを10ドルでホックしようとしている機能...メールアドレスの再登録(ログイン)がすでに存在していることを示し、更新を行います。その場合、データベースに一意のキーが設定されているため、挿入は単に失敗します。読者の皆さんにルックアップを任せて、「メールはすでに登録されています」と言います。

    スキーマ

    CREATE TABLE `user_accounts2` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `email` varchar(100) NOT NULL,
      `password` varchar(255) NOT NULL,
      PRIMARY KEY (`id`),
      unique key(email) -- that better be the case
    ) ENGINE=InnoDB;
    

    register.phpを実行してユーザーを保存すると、データは次のようになります。

    select * from user_accounts2;
    +----+-----------+--------------------------------------------------------------+
    | id | email     | password                                                     |
    +----+-----------+--------------------------------------------------------------+
    |  1 | [email protected]   | $2y$10$U6.WR.tiOIYNGDWddfT7kevJU8uiz8KAkdxXpda9e1xuplhC/eTJS |
    +----+-----------+--------------------------------------------------------------+
    

    最初のmysqliセクション

    register.php

    <?php
        mysqli_report(MYSQLI_REPORT_ALL);
        error_reporting(E_ALL); // report all PHP errors
        ini_set("display_errors", 1); // display them
        session_start();
    
        if(isset($_SESSION['userid'])!="") {
            // you are already logged in as session has been set
            header("Location: safe.php");   // note that this re-direct will at the top of that page
            // ... and there to verify the session state so no tricks can be performed
            // no tricks and gimmicks
        }
    
        if(isset($_POST['register'])) {
            $email = $_POST['email'];
            $ctPassword = $_POST['password'];   // cleartext password from user
            $hp=password_hash($ctPassword,PASSWORD_DEFAULT); // hashed password using cleartext one
    
            // 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
            // end pretend
    
            try {
                $mysqli= new mysqli($host, $user, $pwd, $dbname,$port);
                if ($mysqli->connect_error) {
                    die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
                }
                //echo "I am connected and feel happy.<br/>";
                $query = "INSERT INTO user_accounts2(email,password) VALUES (?,?)";
                $stmt = $mysqli->prepare($query);
    
                // note the 2 s's below, s is for string
                $stmt->bind_param("ss", $email,$hp);    // never ever use non-sanitized user supplied data. Bind it
                $stmt->execute();
                // password is saved as hashed, will be verified on login page with password_verify()
                $iLastInsertId=$mysqli->insert_id;  // do something special with this (or not)
                // redirect to some login page (for now you just sit here)
                $stmt->close(); 
                $mysqli->close();
            } catch (mysqli_sql_exception $e) { 
                throw $e; 
            } 
        }
    ?>
    <html>
    <head>
    <title>Register new user</title>
    </head>
    <body>
    <div id="reg-form">
    <form method="post">
        <table>
            <tr>
            <td><input type="email" name="email" placeholder="Email" required /></td>
            </tr>
            <tr>
            <td><input type="password" name="password" placeholder="Password" required /></td>
            </tr>
            <tr>
            <td><button type="submit" name="register">Register</button></td>
            </tr>
            <tr>
            <td><a href="index.php">Normal Login In Here</a></td>
            </tr>
        </table>
    </form>
    </div>
    </body>
    </html>
    

    login.php

    <?php
        mysqli_report(MYSQLI_REPORT_ALL);
        error_reporting(E_ALL); // report all PHP errors
        ini_set("display_errors", 1); // display them
        session_start();
    
        if(isset($_SESSION['userid'])!="") {
            // you are already logged in as session has been set
            header("Location: safe.php");   // note that this re-direct will at the top of that page
            // ... and there to verify the session state so no tricks can be performed
            // no tricks and gimmicks
        }
    
        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; // comes along for the ride so I don't need to look up param order below
            // end pretend
    
            try {
                $mysqli= new mysqli($host, $user, $pwd, $dbname,$port);
                if ($mysqli->connect_error) {
                    die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
                }
                //echo "I am connected and feel happy.<br/>";
                $query = "select id,email,password from user_accounts2 where email=?";
                $stmt = $mysqli->prepare($query);
    
                // note the "s" below, s is for string
                $stmt->bind_param("s", $email); // never ever use non-sanitized user supplied data. Bind it
                $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'];
                        // redirect to safe.php (note safeguards verbiage at top of this file about it)
                    }
                    else {
                        echo "wrong";
                        // could be overkill here, but in logout.php
                        // clear the $_SESSION['userid']
                    }
                }
                else {
                    echo 'no such record';
                }
                // remember, there is no iterating through rows, since there is 1 or 0 (email has a unique key)
                // also, hashes are one-way functions in the db. Once you hash and do the insert
                // there is pretty much no coming back to cleartext from the db with it. you just VERIFY it
    
                $stmt->close(); 
                $mysqli->close();
            } catch (mysqli_sql_exception $e) { 
                throw $e; 
            } 
        }
    ?>
    <html>
    <head>
    <title>Login</title>
    </head>
    <body>
    <div id="reg-form">
    <form method="post">
        <table>
            <tr>
            <td><input type="email" name="email" placeholder="Email" required /></td>
            </tr>
            <tr>
            <td><input type="password" name="password" placeholder="Password" required /></td>
            </tr>
            <tr>
            <td><button type="submit" name="login">Login</button></td>
            </tr>
        </table>
    </form>
    </div>
    </body>
    </html>
    

    以下のpdoセクション

    時間があるときは、おそらく明日ですが、今のところ、この私の回答 を紹介します。 。




    1. VARCHARからINTへのキャスト-MySQL

    2. PLS-00428:このSELECTステートメントでINTO句が必要です

    3. 夏時間を念頭に置いて繰り返し日付を保存する方法

    4. ゲームの先を行くSQLServerパフォーマンスメトリクス