2017-10-18 509 views
1

如果问题看起来很愚蠢,我真的很抱歉。但是,我一直试图几天来检查我usernamepassword数据库匹配我在html页我打字......这是我的登录表单...如何检查用户名和密码是否与数据库值匹配

<form method="POST" action="Dashboard/Dashboard.php"> 

    <div class="form-group md-form"> 
     <!--<input type="email" class="form-control" id="email" value="" placeholder="Enter email address">--> 
     <i class="fa fa-user prefix grey-text"></i> 
     <input name="username" id="username" type="text" class="form-control" required> 
     <label for="defaultForm-email">Username</label> 
    </div> 
    <div class="form-group md-form"> 
     <!--<input type="password" class="form-control" id="password" value="" placeholder="Enter password">--> 
     <i class="fa fa-lock prefix grey-text"></i> 
     <input name="password" id="password" type="password" class="form-control" required> 
     <label for="defaultForm-pass">Your password</label> 
    </div> 
    <div class="text-center"> 
     <button type="reset" class="btn btn-amber btn-sm"><strong>Reset</strong></button> 
     <input type="submit" name="submit" id="submit" class="btn btn-green btn-sm" value="Sign in">           
    </div> 

</form> 

这是代码(php)我使用的Dashboard.php

<?php 
    $servername = "localhost"; 
    $username = "root"; 
    $password = ""; 
    $databaseName = "test"; 

    $conn = mysqli_connect($servername, $username, $password, $databaseName); 

    $un = $_POST['username']; 
    $pw = $_POST['password']; 
    print $pass . "_" . $email; 

    $query = mysqli_query($conn, "SELECT log_username,log_password FROM login WHERE log_username='$un' AND log_password='$pw'"); 

    $result_can = mysqli_query($conn, $query); 


    while ($row = mysql_fetch_assoc($result_can)) { 


     $check_username = $row['username']; 
     $check_password = $row['password']; 
    } 
    if ($un == $check_username && $pw == $check_password) { 
     $message = "ok"; 
     echo "<script type='text/javascript'>alert('$message');</script>"; 
     header("Location: Doctors.php"); 
    } else { 
     $message = "No"; 
     echo "<script type='text/javascript'>alert('$message');</script>"; 
     header("Location: Doctors.php"); 
    } 
    ?> 

我真的试过像几千倍,但无法弄清楚我哪里错了...任何人都可以帮我吗?

我知道我的代码是开放给SQL注入的,但我不在乎它,因为这是我需要向我的朋友展示的一个示例因此忽视该部分。

+6

“*我知道我的代码对SQL注入是开放的,但我不在乎*”。一些有史以来最危险的词:) –

+3

为什么要向你的朋友展示一个没有人应该做的事情的例子?向他们展示如何从一开始就正确地做到这一点。另外,你还没有真正说明你实际上*有什么问题。 – Sammitch

+0

https:// stackoverflow。com/help/mcve – Sammitch

回答

4

堆栈溢出是 “专业和发烧级的程序员。”尊敬的你已经向我们展示了你的问题中的代码,它甚至不值得任何名称。

StackOverflow人对幽默安全代码没有多少幽默感。你会对你的代码产生强烈的反应,因为Equifax,Ashley Madison和Adobe以及网络犯罪分子破解的所有其他地方。为什么我们跳上你?因为我们不喜欢网络罪犯,我们不想让他们的生活变得轻松。朋友不要让朋友做坏密码安全。朋友不会向朋友展示严重不安全的密码验证代码。

你的代码有什么问题?您将密码存储为纯文本,并且您很容易受到SQL注入攻击。我将解决第一个问题。

幸运的是,php有很好的密码安全设施。在这里阅读有关它们。 http://php.net/manual/en/faq.passwords.php使用它们。你如何处理密码?

  1. 当用户在您的网站上注册并首次提供密码时,您会对其进行哈希处理,如下所示。
$usersPassword = $_POST['password']); 
    $hash = password_hash($usersPassword , PASSWORD_DEFAULT); 
    // you then store the username and the hash in your dbms. 
    // the column holding the hash should be VARCHAR(255) for future-proofing 
    // NEVER! store the plain text (unhashed) password in your database 
  • 当用户尝试登录,你做这样的查询:

    SELECT log_password FROM log_user WHERE log_username = TheUsernameGiven 
    

    然后你把检索到的密码进入一列名为$hash

    然后,您使用php's password_verify() function来检查您的可能用户刚刚给您的密码是否与数据库中的密码相符。

    最后,您检查用户的密码是否需要重新设置,因为之前用于哈希的方法已过时。

  • $usersPassword = $_POST['password']); 
    $valid = password_verify ($usersPassword, $hash); 
    if ($valid) { 
        if (password_needs_rehash ($hash, PASSWORD_DEFAULT)) { 
        $newHash = password_hash($usersPassword, PASSWORD_DEFAULT); 
        /* UPDATE the user's row in `log_user` to store $newHash */ 
        } 
        /* log the user in, have fun! */ 
    } 
    else { 
        /* tell the would-be user the username/password combo is invalid */ 
    } 
    

    这个序列是面向未来的,因为它可以在以后老调重弹的密码,如果旧的哈希方法获取太容易了cybercreeps破解。

    +0

    非常感谢您先生:)这工作! – user8794865

    1

    这里有几个问题,无论是在你的代码还是在思考过程中。让我们以自己的方式下:

    $un = $_POST['username']; 
    $pw = $_POST['password']; 
    print $pass . "_" . $email; 
    

    print线应该可以给你一个警告。变量$pass$email不存在。您应该删除该行,除非您尝试要做的是要打印$un$pw

    $query = mysqli_query($conn, "SELECT log_username,log_password FROM login WHERE log_username='$un' AND log_password='$pw'"); 
    

    没有必要同时选择用户名和密码列。如果有匹配,它们将始终与您已拥有的$un$pw相同。您只是检查用户名和密码是否正确,因此选择单个列就足够了。最好是用户名,但只有用户名就足够了。请注意,假设查询成功执行,$query将包含一个mysqli_result对象。

    $result_can = mysqli_query($conn, $query); 
    

    此行需要删除。你已经执行了你的查询,并且$query是它的结果,你在这里做的没有意义,应该给你一个警告,或者甚至是一个致命的错误。

    while ($row = mysql_fetch_assoc($result_can)) { 
        $check_username = $row['username']; 
        $check_password = $row['password']; 
    } 
    if ($un == $check_username && $pw == $check_password) { 
        $message = "ok"; 
        echo "<script type='text/javascript'>alert('$message');</script>"; 
        header("Location: Doctors.php"); 
    } else { 
        $message = "No"; 
        echo "<script type='text/javascript'>alert('$message');</script>"; 
        header("Location: Doctors.php"); 
    } 
    

    不能混合mysql_*mysqli_*功能。在这里使用mysql_fetch_assoc()应该会给你一个致命的错误。您应该使用mysqli_fetch_assoc()来代替(在$query而不是$result_can),但是:

    ,因为你只在是否有任何结果在所有感兴趣,这整段可以改成:

    if (mysqli_num_rows($query) > 0) { 
        $message = "ok"; 
        echo "<script type='text/javascript'>alert('$message');</script>"; 
        header("Location: Doctors.php"); 
    } else { 
        $message = "No"; 
        echo "<script type='text/javascript'>alert('$message');</script>"; 
        header("Location: Doctors.php"); 
    } 
    

    这会带来其他问题,因为您不能使用header()在回显您的<script>标记后重定向用户(您将收到“头文件已发送”错误)。如果您想要JavaScript警报,请使用Javascript执行重定向。同样,$message变量是没有用处,还不如直接把消息进入警戒状态:

    if (mysqli_num_rows($query) > 0) { 
        echo "<script type='text/javascript'>alert('ok'); window.location.href='Doctors.php';</script>"; 
    } else { 
        echo "<script type='text/javascript'>alert('No'); window.location.href='Doctors.php';</script>"; 
    } 
    

    一旦你解决这些问题都,你仍然有一些思考的事情。

    • 您应该从不在数据库中以纯文本格式存储密码。
    • 您可能不关心SQL注入的权利,但与当前查询我可以通过输入自己的用户名作为admin' AND 1 --任何有效的用户(例如,“管理员”)登录,或者如果我只是想获得我可以使用一个用户名的any' OR 1 --,并作为表中的第一个用户登录。查看准备好的陈述以及它们的工作方式。
    • 你有没有错误处理的。您应该添加检查以查看数据库连接是否已成功打开,查询是否正确执行,表单是否已发布以及用户名/密码字段是否已填写,并考虑如何向用户显示有用的错误消息。

    这里的主要教训应该是:当您开发并且无法正常工作时,请始终检查错误日志以查看它是否包含任何提示并打开PHP的错误报告功能,以便您可以看到您在你的浏览器中做错了。

    +0

    非常感谢您的先生:) – user8794865

    1

    几个问题,有的被评论上述。

    混合mysql_ *与mysqli_ * API

    与您通话mysqli_query()查询,但你尝试用mysql_fetch_assoc()获取结果。你不能混用这些不同的API。 mysql_*函数不会使用您使用mysqli_connect()打开的连接,反之亦然。选择一个MySQL扩展并坚持下去。

    提示:不要使用mysql_*在所有。它的过时,已经从PHP 7.0+

    用户名和密码

    只要搜索的用户名,并获取密码查询条件删除。如果搜索均为,那么搜索将返回零行,除非使用了正确的密码。

    你不希望出现这种情况。您希望避免将明文密码放入SQL查询中。只需搜索用户名,并获取存储的密码,然后比较您获取的用户输入密码。

    未初始化变量

    如果您从您的查询取零行,然后$check_username$check_password永远不会置。然后你比较你的if语句中的那些变量。不是一个致命的错误,但风格不好。

    无密码散列

    你似乎是比较用户输入的,我以为是明文的,直接到什么是存储在数据库中。 You're Probably Storing Passwords Incorrectly.

    相反,当你存储你的密码,先用password_hash()

    没有查询参数

    我知道你说你不关心你的SQL注入漏洞,但这就像是一名电工,说你不关心您的电气面板塞满了含油抹布。请务必在LinkedIn个人资料中张贴您对安全的漠视,让雇主知道应该避免哪些问题。

    推荐实施

    mysqli_report(MYSQLI_REPORT_STRICT); // enable exceptions 
    
    $conn = new mysqli($servername, $mysql_username, $mysql_password, $databaseName); 
    
    $log_username = $_POST['username']; 
    $log_password = $_POST['password']; 
    
    $sql = "SELECT log_username, log_password_hash FROM login WHERE log_username=?"; 
    $stmt = $conn->prepare($sql); 
    $stmt->bind_param('s', $log_username); 
    $stmt->execute(); 
    $result = $stmt->get_result(); 
    
    while ($row = $result->fetch_assoc()) { 
        if (password_verify($log_password, $row['log_password_hash'])) { 
         $message = "ok"; 
         // header must be called before any other output 
         header("Location: Doctors.php"); 
         exit(); 
        } 
    } 
    $message = "No"; 
    // header must be called before any other output 
    header("Location: Doctors.php"); 
    
    +0

    非常感谢您先生... – user8794865

    相关问题