在Web数据库中存储密码?

时间:2015-10-16 14:56:22

标签: database passwords

所以,我想要实现的目标如下: 当您进入网站时,只有一个密码框。如果输入的密码与数据库中的密码匹配,则会打开一个包含更多信息的弹出窗口。我该怎么做呢?

1 个答案:

答案 0 :(得分:0)

让我们解决你的问题:

  • 您需要一个允许用户登录的索引页
  • 要允许用户登录,您需要使用联系某种登录功能的表单(最简单的方法)或AJAX请求(稍微更难的方法)。 (我将在我的示例中使用PHP,但您可以根据需要使用其他语言。)
  • 在PHP脚本中,您需要能够访问数据库。 (MySQLiPDO是目前推荐的PHP类。)
  • 连接到数据库后,您需要查询数据库以从表中获取相关行。
  • 现在,您需要从行中获取数据并执行必要的检查。
  • 最后,您需要将一些数据返回给浏览器,以便浏览器知道下一步该做什么。 (确保您的代码能够回答以下问题:登录成功了吗?应该打开什么弹出窗口?应该显示什么错误消息?应该设置什么cookie?等等。)

网站登录的内容多于此,但这只是您问题的一般细分。

以下是我将在您的示例中使用的内容:   - 我将使用PHP作为动态服务器端脚本   - 我将使用一些JavaScript(只是vanilla JS,而不是jQuery或其他变体)来为AJAX提供登录请求。 显然,您可以随意在实施中使用其他内容。

我首先要创建index.html,如下所示:

<!DOCTYPE html>
<html lang="en"> <!-- Assuming the language is English -->
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Some Snazzy Title for Login Page</title>
        <script type="text/javascript" src="resources/js/functions.js"></script>
        <!-- Any additional things you want to include in the head of the HTML page -->
    </head>
    <body>
        <!-- Table is used here for formatting -->
        <table id="LoginTable" style="margin-left:auto;margin-right:auto;">
            <tr>
                <td>Username:</td>
                <td><input type="text" name="username" id="username"></td>
            </tr>
            <tr>
                <td>Password:</td>
                <td><input type="password" name="password" id="password"></td>
            </tr>
        </table>
        <br>
        <!--- Button to call our JavaScript AJAX login function: -->
        <button onclick="AttemptLogin();">Login</button>
        <!--- Include links to things like register, forgot password, and etc. here -->
    </body>
</html>

正如您所注意到的,我们包含一个名为functions.js的外部JavaScript文件,该文件位于 resources / js / 子目录中。因此,要包含此内容,您需要在与index.html相同的目录中创建一个名为 resources 的文件夹,然后在<<1>}内创建一个名为 js 的文件夹。 em> resources 文件夹。完成后,我们已准备好创建functions.js

/* Credits to Minko Gechev (blog.mgechev.com) for createXMLHttp() (I have made my own modifications to it, though.) */
function createXMLHttp(){
        //If XMLHttpRequest is available then using it
    if (typeof XMLHttpRequest !== undefined) {
        // XMLHttpRequest is a fairly standard class in most browsers for handling AJAX, but
        // it's not defined in all browsers (including IE)
        return new XMLHttpRequest;
    } else if (window.ActiveXObject) {
        // User is using Internet Explorer
        // Now we'll try to use an array of various IE XML HTTP types to find the right one:
        var ieXMLHttpVersions = ['Microsoft.XMLHTTP', 'MSXML2.XMLHttp.5.0', 'MSXML2.XMLHttp.4.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp', 'Microsoft.XMLHttp'];
        var xmlHttp;

        // Look through the array and try to create the XMLHttp object
        for (var i = 0; i < ieXMLHttpVersions.length; i++) {
            try {
                xmlHttp = new ActiveXObject(ieXMLHttpVersions[i]);
                return xmlHttp;
            } catch (e) {
                // Do nothing with error
            }
        }

        // Despite the fact that ActiveXObject is defined, none of the XMLHttp versions could be
        // successfully created. The browser's JavaScript implementation is unknown and thus we cannot
        // use AJAX for this.
        return null;
    }else{
        // This browser is unknown and it does not support any of the common XML HTTP classes.
        // As such, we will not be able to AJAX for login through this.
        return null;
    }
}

function AttemptLogin(){
    // First we'll get the current timestamp which we'll append to the login link to prevent caching:
    var timestamp = new Date().getTime();
    // Link to POST login data to (with cache-buster):
    var url = "ajax/login_process.php?cachebuster=" + timestamp;
    var username = encodeURIComponent(document.getElementById("username").value);
    var password = encodeURIComponent(document.getElementById("password").value);

    var PostRequestData = "u=" + username + "&p=" password";

    var xmlHttp = createXMLHttp();

    if(xmlHttp === null){
        // xmlHttp could not be successfully created
        // Alert the user of this issue and recommend a browser upgrade
        alert("An error occurred that prevented us from logging in.\nThis issue seems to have been caused by your browsers JavaScript implementation. Please consider updating your browser to the newest version or installing a different browser.");
        // Exit the function prematurely
        return;
    } // Else, xmlHttp appears to have been created successfully

    xmlHttp.open('POST', url, true);
    xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    // Code the callback function which will be executed after the request completes.
    xmlHttp.onreadystatechange = function(){
        if( xmlHttp.readyState == 4 && xmlHttp.status == 200 ){
            // It seems like the request successfully executed
            // Now we'll just need to check if the login was successful or not:
            var respText = xmlHttp.responseText;

            if(respText.indexOf("login success") > -1){
                // Now we'll open a popup window here:
                window.open('info.phtml', 'More Information', 'height=400,width=400');
                // Info.phtml will do additional security checks before displaying the information, by the way.
            }else{
                alert("Error: either the username does not exist or the is incorrect for the username provided.\nPlease try again.");
            }
        }
    }

    // Now that we have the request open, the request header is set, and the callback
    // function is defined, we will finally send the actual login request to the login_process.php page:
    xmlHttp.send(PostRequestData);
}

现在我们需要写出login_process.php的代码。不过,在此之前,我们需要创建这个文件的目录。因此,在放置index.html文件的同一文件夹中,您应该创建一个名为 ajax 的子目录。现在我们将编写该文件夹中的login_process.php文件:

<?php
    // Start up a session so we can hold whether the user is logged in or not:
    session_start();

    // To further prevent caching we'll use these headers:
    header("Cache-control: no-store, no-cache, must-revalidate");
    header("Expires: " . gmdate("D, d M Y H:i:s", (time() + 2)) . " GMT");
    header("Date: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Pragma: no-cache");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");

    // Make sure the request is valid:
    if($_SERVER['REQUEST_METHOD'] != 'POST'){
        die("Invalid request type");
    }

    // Now let's do the login.
    // First, connect to the database:
    $mysqli = new mysqli("Your database host", "Your database username", "Your database password", "The database name");

    if($mysqli->connect_errno){
        die("Failed to connect to database");
    }

    // Next we'll get the request parameters
    $username = $_POST['u'];
    $password = $_POST['p'];

    // Now we need to clean the username so we can search the database for it
    $safeUsername = $mysqli->real_escape_string($username); // Prevents SQL injection

    // Next let's query to see if this username exists:
    $result = $mysqli->query("SELECT * FROM `TableName` WHERE `username`='$safeUsername' LIMIT 1;");

    if($result->num_rows == 0){
        // The username is unknown.
        // Close the database members and die with vague error message
        $result->free();
        $mysqli->close();
        die("fail");
    } // Else, username exists

    // Get this user's salts and password hash:
    $row = $result->fetch_assoc();

    // Now that we have the results as a PHP keyed array, we do not need to keep
    // the database open any longer. So we will now close the database connection and
    // free the database-related objects from the memory.
    $result->free();
    $mysqli->close();

    // Now pull out the database provided values to local variables (for convenience):
    $passwordSalt_1 = $row['salt1'];
    $passwordSalt_2 = $row['salt2'];
    $passwordHash = strtolower($row['passHash']); // Hexdigest of users current password hash

    // Hash the users password with the salt and see if the results match:
    $userPasswordData = $passwordSalt_1 . $password . $passwordSalt_2;
    $requestedPassHash = strtolower(hash('sha512', $userPasswordData));

    // Now we just need to see if the user's passHash in the database is the same as
    // the hash we just generated via the password sent in the request:
    $isLoggedIn = ($passwordHash == $requestedPassHash);

    $_SESSION['logged_in'] = ($isLoggedIn ? '1' : '0');

    // Send back the login result to the AJAX callback function:
    die(($isLoggedIn ? "login success" : 'fail'));
?>

现在我们剩下的就是编码info.phtml(弹出式网页):

<?php
    // Start up the session so we can access the session variables:
    session_start();

    // We certainly don't want the browser to cache our webpage which should require login:
    header("Cache-control: no-store, no-cache, must-revalidate");
    header("Expires: " . gmdate("D, d M Y H:i:s", (time() + 2)) . " GMT");
    header("Date: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Pragma: no-cache");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");

    // Now we'll simply check if the user is logged in by referencing the session:
    if( !isset($_SESSION['logged_in']) || // Check if session variable is set
        empty($_SESSION['logged_in']) || // Check if the variable isn't empty
        ($_SESSION['logged_in'] != '1') ){ // Check if the variable is anything other than the valid value

        // If any of the above statements are true, we reach this code and the user is not properly logged in
        // As such, we should display an error page message instead of displaying the page.
        header($_SERVER["SERVER_PROTOCOL"] . " 418 I'm a teapot", true, 418);
        /* Personal Note: I'm using 418 'I'm a teapot' here out of personal preference.
           Technically the RFC has not defined a response code for telling a user that they need
           to login to the website before accessing the page, but sending back a non-4xx response
           does not seem reasonable. 4xx response codes tell the client that there was an error
           with their request. Since this wasn't a server a error and the request did not go over
           successfully, a level 4xx response is the most fitting. */

        die("Error: You need to login before accessing this page.");
    } // Else, the user is logged in. Go ahead and show them the page.
?>

希望这有助于您设置网站。如果这确实有帮助,请不要忘记upvote。 (不是试图乞求,但我确实花了很长时间写下你的问题的答案:P)我没有测试提供的代码,所以我确信整个过程中可能会有一些小错误。显然,您需要重写代码的某些部分以适应您的情况,但总的来说,它应该让您深入了解这种可以编码的系统。