简体   繁体   English

如何使用php重定向到另一个HTML文件

[英]How to redirect to another html file using php

I'm trying to create a form that authenticates a username and password that exists in a MySQL database (using UwAmp ) It has a database called users and a table called userdetails that has 2 columns Username and Password both contain user and pass respectively as data. 我正在尝试创建一个表单来验证MySQL数据库中存在的用户名和密码(使用UwAmp ),该UwAmp具有一个名为users的数据库和一个名为userdetails的表,该表有2列UsernamePassword分别包含user和作为数据pass

I know I'm not using the best most up to date security methods at the moment (I want to learn that after doing this). 我知道我目前没有使用最好的最新安全方法(我想在做完这些之后再学习)。

At the moment that page remains on login.php regardless if the details are correct, in both circumstances, everything disappears on the page. 无论详细信息是否正确,此页面仍保留在login.php ,在两种情况下,页面上的所有内容均消失。

As a side note I may be getting this confused but is there a way of storing a password in a UwAmp database that isn't just plain text. 附带说明一下,我可能对此感到困惑,但是有一种方法可以将密码存储在不只是纯文本的UwAmp数据库中。 Can I encrypt it? 我可以加密吗?

I have the following PHP file 我有以下PHP文件

<?php

    include_once '/includes/db-connect.php'; //Connect to the database
    if(isset($_POST["Username"], $_POST["Password"])) 
    {     

        $name = $_POST["Username"]; 
        $password = $_POST["Password"]; 

        $result1 = mysqli_query($conn, "SELECT Username, Password FROM userdetails WHERE Username = '".$name."' AND  Password = '".$password."'");

        while($row=mysql_fetch_assoc($result1))
        {
           $check_username=$row['Username'];
           $check_password=$row['Password'];
        }

        if($username == $check_username && $password == $check_password) {
           header("Location: welcomePage.html");
        }
        else { 
           echo "No match.";
        }
    }

HTML file HTML文件

<div class="form_login">


<form name="credentials" action="php/login.php" onsubmit="return validateForm();" method="post">
             Username:<br>
  <input type="text" name="Username" value=""><br>
  Pasword:<br>
  <input type="password" name="Password" value=""><br><br>
  <input type="submit" value="Submit">
</form>


          </div>

errors. 错误。

( ! ) Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in C:\Users\user\Documents\examplePHP\UAMP\UwAmp\www\techTest\php\login.php on line 1

( ! ) Notice: Undefined variable: check_username in C:\Users\user\Documents\examplePHP\UAMP\UwAmp\www\techTest\php\login.php on line 18

The problem is with your query string, as double quote (") can interprete $variables while single quote(') cannot. So remove single quotes in it and keep all query string in double quotes like this; 问题出在您的查询字符串上,因为双引号(“)可以解释$ variables,而单引号(')不能。

$result1 = mysqli_query($conn, "SELECT Username, Password FROM userdetails WHERE Username = '".mysqli_escape_string($conn,$name)."' AND Password = '".mysqli_escape_string($conn,$password)"';"); $ result1 = mysqli_query($ conn,“从用户处选择SELECT用户名,密码,用户名='” .mysqli_escape_string($ conn,$ name)。“'AND Password ='” .mysqli_escape_string($ conn,$ password)“'';” );

Updated php file: 更新的php文件:

<?php

    include_once '/includes/db-connect.php'; //Connect to the database
    if(isset($_POST["Username"], $_POST["Password"])) 
    {     

        $name = $_POST["Username"]; 
        $password = $_POST["Password"]; 

        $result1 = mysqli_query($conn, "SELECT Username, Password FROM userdetails WHERE Username = '".mysqli_escape_string($conn,$name)."' AND  Password = '".mysqli_escape_string($conn,$password)"';");

        while($row=mysql_fetch_assoc($result1))
        {
           $check_username=$row['Username'];
           $check_password=$row['Password'];
        }

        if($username == $check_username && $password == $check_password) {
           header("Location: welcomePage.html");
        }
        else { 
           echo "No match.";
        }
    }

I would then refer you to the PHP doc on the hash() call 然后,我将带您参考hash()调用中的PHP文档。

http://php.net/manual/en/function.hash.php http://php.net/manual/zh/function.hash.php

You can try any number of hash encrypts to see which one works best for you. 您可以尝试任意数量的散列加密,以查看哪种散列加密最适合您。 You are correct by saying that md5() is not considered secure enough by modern industry standards. 正确地说,现代行业标准认为md5()不够安全。

Otherwise there are some libraries on gitHub that might work as well. 否则,gitHub上的某些库也可能会正常工作。 But... they may not work. 但是...它们可能不起作用。

Hope that helps. 希望能有所帮助。

As an a simple unsecured key it would be. 作为一个简单的不安全密钥。

$password = $_POST['password'];

$encrypted_password = hash(-hash_algorith-, $password);

Then insert into SQL or check for validity 然后插入SQL或检查有效性

-Hope that helps -希望有帮助

Short notes first: 首先简短说明:

  • The warning mysql_fetch_assoc() expects parameter 1 to be resource, boolean given ... was probably raised because mysqli_query returned FALSE - the value used to signalize a failure - instead of a mysqli_result (see this ). 警告mysql_fetch_assoc() expects parameter 1 to be resource, boolean given ...可能是因为上调返回mysqli_query FALSE -用于发送信号指示失败的价值-而不是mysqli_result (见 )。 Why you have this situation, it's up to you to find out. 为什么会遇到这种情况,这取决于您自己确定。 I didn't saw any inadvertence which might have produced it. 我没有看到任何可能导致它的疏忽。
  • The notice Undefined variable: check_username ... is raised in the case when no record is found in the db table. 在db表中未找到任何记录的情况下,将引发通知Undefined variable: check_username ... In that case, the variable definitions and the values assignation inside of while statement don't take place. 在这种情况下, while语句内部的变量定义和值分配不会发生。 Therefore, outside of while statement the variables $check_username and $check_password are "recognized" as not defined. 因此,在while语句之外,变量“ $check_username和“ $check_password被“识别”为未定义。
  • Don't forget to call exit() after the redirectioning code, eg after sending the Location response header. 不要忘记在重定向代码之后(例如在发送Location响应头之后调用exit()

Now, your first big problem is, that you don't use any prepared statements in order to avoid SQL injection . 现在,您的第一个大问题是,为了避免SQL注入 ,您不使用任何准备好的语句 So, instead of mysqli_query , you should definitely use the functions involved in preparing an sql statement - in this case yours - and injecting the values for eventual parameter markers found in it. 因此,除了mysqli_query之外 ,您绝对应该使用准备sql语句所涉及的功能(在本例中为您的sql语句),并为其中找到的最终参数标记注入值。

The second big problem would be, indeed, if you would decide to save the password in clear text, or in a not secure form - like md5. 第二个大问题确实是,如果您决定以明文形式或不安全的形式(例如md5)保存密码。 The password should be strongly encrypted. 密码应严格加密。 For this task I would recommend you to use the password_hash function - either with the PASSWORD_BCRYPT option (a constant defining the Blowfish hashing algorithm), or with the PASSWORD_ARGON2I option (constant defining the Argon2 hashing algorithm and introduced as of PHP 7.2.0). 对于此任务,我建议您使用password_hash函数-通过PASSWORD_BCRYPT选项(定义Blowfish哈希算法的常量),或使用PASSWORD_ARGON2I选项(常数定义Argon2哈希算法,自PHP 7.2.0起引入)。 You should thoroughly read the documentation of password_hash and of the used constants. 您应该彻底阅读password_hash和使用的常量的文档。 You might maybe want to read this post too. 您可能也想阅读这篇文章

I wrote a code version below, implementing the two points above, in the hope that it will bring more clarity. 我在下面编写了一个代码版本,实现了以上两点,希望它能带来更多的清晰度。 I used the object-oriented mysqli library (instead of the procedural one) and my naming/coding conventions though (inclusive for the db table) - so, as I would apply them in my project. 我使用了面向对象的mysqli库(而不是过程库)和命名/编码约定(包括db表),因此,就像我在项目中应用它们一样。 It also contains a credentials validation part on the server-side. 它还在服务器端包含一个凭证验证部分。 A required step, actually. 实际上,这是必需的步骤。

In principle, before creating a login.php code, you should create a page responsible with saving user credentials in the db table. 原则上,在创建login.php代码之前,您应该创建一个页面,负责将用户凭据保存在db表中。 In that page ( create-user.php for example), for the given password a password hash will be created (using the password_hash function) and saved. 在该页面(例如create-user.php )中,将为给定的密码创建一个密码哈希(使用password_hash函数)并保存。 The hash will be a string of minimum 60 aleatory characters. 哈希将是至少60个字母的字符串。 The relevant page code would look like this: 相关页面代码如下所示:

//...

$username = $_POST['username'];
$password = $_POST['password'];

// Create a hash from the posted password.
$passwordHash = password_hash($password, PASSWORD_BCRYPT);

$sql = 'INSERT INTO user_credentials (username, password) VALUES (?, ?)';

$statement = $connection->prepare($sql);
$statement->bind_param('ss', $username, $passwordHash);
$statement->execute();

//...

But, in order to shorten the task for now, you can create in PHP a password hash from the value pass and copy and save it manually, along with the user value: 但是,为了暂时缩短任务,您可以在PHP中pass值创建密码哈希,然后手动复制并保存它以及user值:

// Create a hash from the "pass" value.
$passwordHash = password_hash('pass', PASSWORD_BCRYPT);
echo $passwordHash;

Suggestion: for applying error/exception handling you could take a look at this and this tutorial articles. 建议:对于应用的错误/异常处理,你可以看看这个这个教程文章。

At last, here is the login page, the db connection code, the table structure and the file system structure that I used: 最后,这是我使用的登录页面,数据库连接代码,表结构和文件系统结构:

login.php login.php

<?php
/* Don't use include_once to include the connection page! */
require 'includes/connection.php';

// Operations upon form submission.
if (isset($_POST['submit'])) {
    // Validate username.
    if (!isset($_POST['username']) || empty($_POST['username'])) {
        $errors[] = 'Please provide the username.';
    } /* Other validations here using "else if". For example on username length. */

    // Validate password.
    if (!isset($_POST['password']) || empty($_POST['password'])) {
        $errors[] = 'Please provide the password.';
    } /* Other validations here using "else if". For example on password length. */

    if (!isset($errors)) { // No errors.
        // Get posted credentials.
        $username = $_POST['username'];
        $password = $_POST['password'];

        /*
         * The SQL statement to be prepared. Notice the so-called markers, 
         * e.g. the "?" signs. They will be replaced later with the 
         * corresponding values when using mysqli_stmt::bind_param.
         * 
         * @link http://php.net/manual/en/mysqli.prepare.php
         */
        $sql = 'SELECT username, password 
                FROM user_credentials 
                WHERE username = ? 
                LIMIT 1';

        /*
         * Prepare the SQL statement for execution - ONLY ONCE.
         * 
         * @link http://php.net/manual/en/mysqli.prepare.php
         */
        $statement = $connection->prepare($sql);

        /*
         * Bind variables for the parameter markers (?) in the 
         * SQL statement that was passed to prepare(). The first 
         * argument of bind_param() is a string that contains one 
         * or more characters which specify the types for the 
         * corresponding bind variables.
         * 
         * @link http://php.net/manual/en/mysqli-stmt.bind-param.php
         */
        $statement->bind_param('s', $username);

        /*
         * Execute the prepared SQL statement.
         * When executed any parameter markers which exist will 
         * automatically be replaced with the appropriate data.
         * 
         * @link http://php.net/manual/en/mysqli-stmt.execute.php
         */
        $statement->execute();

        /*
         * Get the result set from the prepared statement.
         * 
         * NOTA BENE:
         * Available only with mysqlnd ("MySQL Native Driver")! If this 
         * is not installed, then uncomment "extension=php_mysqli_mysqlnd.dll" in 
         * PHP config file (php.ini) and restart web server (I assume Apache) and 
         * mysql service. Or use the following functions instead:
         * mysqli_stmt::store_result + mysqli_stmt::bind_result + mysqli_stmt::fetch.
         * 
         * @link http://php.net/manual/en/mysqli-stmt.get-result.php
         * @link https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result
         */
        $result = $statement->get_result();

        /*
         * Fetch the credentials into an associative array.
         * If no record is found, the operation returns NULL.
         */
        $credentials = $result->fetch_array(MYSQLI_ASSOC);

        /*
         * Free the memory associated with the result. You should 
         * always free your result when it is not needed anymore.
         * 
         * @link http://php.net/manual/en/mysqli-result.free.php
         */
        $result->close();

        /*
         * Close the prepared statement. It also deallocates the statement handle.
         * If the statement has pending or unread results, it cancels them 
         * so that the next query can be executed.
         * 
         * @link http://php.net/manual/en/mysqli-stmt.close.php
         */
        $statement->close();

        /*
         * Close the previously opened database connection. Not really needed, 
         * because PHP closes the connection after script processing finishes.
         * 
         * @link http://php.net/manual/en/mysqli.close.php
         */
        $connection->close();

        if (isset($credentials) && $credentials) { // Record found.
            $fetchedUsername = $credentials['username'];
            $fetchedPasswordHash = $credentials['password'];

            /*
             * Compare the posted username with the one saved in db and the posted
             * password with the password hash saved in db using password_hash.
             * 
             * @link https://secure.php.net/manual/en/function.password-verify.php
             * @link https://secure.php.net/manual/en/function.password-hash.php
             */
            if (
                    $username === $fetchedUsername &&
                    password_verify($password, $fetchedPasswordHash)
            ) {
                header('Location: welcome.html');
                exit();
            } else {
                $errors[] = 'Invalid credentials. Please try again.';
            }
        } else {
            $errors[] = 'No credentials found for the given user.';
        }
    }
}

echo '<pre>' . print_r(password_hash('pass', PASSWORD_BCRYPT), TRUE) . '</pre>';
?>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes" />
        <meta charset="UTF-8" />
        <!-- The above 3 meta tags must come first in the head -->

        <title>Demo - Login</title>

        <script src="https://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>

        <script type="text/javascript">
            $(document).ready(function () {
                $('#username').focus();
            });

            function validateForm() {
                return true;
            }
        </script>

        <style type="text/css">
            body {
                padding: 30px;
            }

            label {
                display: block;
                font-weight: 400;
            }

            input[type="text"],
            input[type="password"] {
                display: block;
                margin-bottom: 20px;
            }

            button {
                display: block;
                padding: 7px 10px;
                background-color: #8daf15;
                color: #fff;
                border: none;
            }

            .messages {
                margin-bottom: 20px;
            }

            .messages .error {
                color: #c00;
            }
        </style>
    </head>
    <body>

        <div class="messages">
            <?php
            if (isset($errors)) {
                foreach ($errors as $error) {
                    ?>
                    <div class="error">
                        <?php echo $error; ?>
                    </div>
                    <?php
                }
            }
            ?>
        </div>

        <div class="form_login">
            <form name="credentials" action="" method="post" onsubmit="return validateForm();">
                <label for="username">Username:</label>
                <input type="text" id="username" name="username" value="<?php echo isset($username) ? $username : ''; ?>">

                <label for="password">Password:</label>
                <input type="password" id="password" name="password" value="<?php echo isset($password) ? $password : ''; ?>">

                <button type="submit" name="submit" value="submit">
                    Submit
                </button>
            </form>
        </div>

    </body>
</html>

includes/connection.php 包括/connection.php

<?php

// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'users');
define('USERNAME', 'youruser');
define('PASSWORD', 'yourpass');

/*
 * Enable internal report functions. This enables the exception handling, 
 * e.g. mysqli will not throw PHP warnings anymore, but mysqli exceptions 
 * (mysqli_sql_exception).
 * 
 * MYSQLI_REPORT_ERROR: Report errors from mysqli function calls.
 * MYSQLI_REPORT_STRICT: Throw a mysqli_sql_exception for errors instead of warnings. 
 * 
 * @link http://php.net/manual/en/class.mysqli-driver.php
 * @link http://php.net/manual/en/mysqli-driver.report-mode.php
 * @link http://php.net/manual/en/mysqli.constants.php
 */
$mysqliDriver = new mysqli_driver();
$mysqliDriver->report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

/*
 * Create a new db connection.
 * 
 * @see http://php.net/manual/en/mysqli.construct.php
 */
$connection = new mysqli(HOST, USERNAME, PASSWORD, DATABASE, PORT);

Create table syntax 创建表语法

CREATE TABLE `user_credentials` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(100) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

File system structure 文件系统结构

includes
    connection.php
login.php
welcome.html

Your code looks solid. 您的代码看起来很稳定。 I would suggest this to add the encryption. 我建议您添加加密。

$password = $_POST[$password];
$password = md5($password);

That should get you where you need to go. 那应该带您去需要的地方。

Hope that helps. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM