【问题标题】:Random Password Function Fails To Validate随机密码功能验证失败
【发布时间】:2017-12-22 00:24:10
【问题描述】:

我正在尝试创建一个 Web 应用程序,用于随机化用户在登录前请求的密码类型。注册页面不对密码进行哈希处理,对于这个演示,我真的不需要对其进行哈希处理。当用户登录时,他们首先提供他们的电子邮件地址,这是从数据库中确认的。 页面代码如下(index.php):

<?php
    require_once 'dbconnect.php';

    /*
    if ( isset($_SESSION['user'])!="" ) {
        header("Location: home.php");
        exit;
    }
    */

    $error = false;

    if( isset($_POST['btn-login']) ) {
        $email = sanitize($_POST['email']);

        if(empty($email)){
            $error = true;
            $emailError = "Please enter your email address.";
        } else if ( !filter_var($email,FILTER_VALIDATE_EMAIL) ) {
            $error = true;
            $emailError = "Please enter valid email address.";
        }
        if (!$error) {

            $stmt = dbconnect()->prepare("SELECT * FROM users WHERE email=:email");
            $stmt->execute(array(
                ":email" => $email,
            ));
            $count = $stmt->rowCount();

            if($count == 1) {
                $_SESSION['email'] = $email;
                    redirect('creds.php');

            } else {
                $errMSG = "Incorrect Credentials, Try again...";
            }

        }

    }
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Coding Cage - Login & Registration System</title>
<link rel="stylesheet" href="assets/css/bootstrap.min.css" type="text/css"  />
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>

<div class="container">

    <div id="login-form">
    <form method="post" autocomplete="off">

        <div class="col-md-12">
            <div class="form-group">
                <h2 class="">Sign In.</h2>
            </div>
            <div class="form-group">
                <hr />
            </div>
            <?php
            if ( isset($errMSG) ) {
                ?>
                <div class="form-group">
                <div class="alert alert-danger">
                <span class="glyphicon glyphicon-info-sign"></span> <?php echo $errMSG; ?>
                </div>
                </div>
                <?php
            }

            ?>
            <div class="form-group">
                <div class="input-group">
                <span class="input-group-addon"><span class="glyphicon glyphicon-envelope"></span></span>
                <input type="email" name="email" class="form-control" placeholder="Your Email" value="<?php if (isset($email)) {echo $email;} ?>" maxlength="40" />
                </div>
                <span class="text-danger"><?php if (isset ($emailError)) {echo $emailError;} ?></span>
            </div>

            <div class="form-group">
                <hr />
            </div>

            <div class="form-group">
                <button type="submit" class="btn btn-block btn-primary" name="btn-login">Next..</button>
            </div>

            <div class="form-group">
                <hr />
            </div>

            <div class="form-group">
                <a href="register.php">Sign Up Here...</a>
            </div>

        </div>

    </form>
    </div>  

</div>

</body>
</html

在填写完该表单后,用户将被重定向到 'creds.php',它应该从 functions.php 中选择一个随机密码函数。 creds.php 代码为:

<?php
require_once 'dbconnect.php';


/*
if ( isset($_SESSION['user'])!="" ) {
    header("Location: home.php");
    exit;
}
*/


$error = false;

if(isset($_POST['btn-login']) ) {
    $pass = sanitize($_POST['pass']);

    $passarray = getrandomfunction($pass);

    echo $passarray;
    if ($passarray == 0)
    {
        $passval = 'reversepass';
    }
    elseif ($passarray == 1)
    {
        $passval = 'passtoupper';
    }
    elseif ($passarray == 2)
    {
        $passval = 'passtolower';
    }
    elseif ($passarray == 3)
    {
        $passval = 'defaultpass';
    }
    elseif ($passarray == 4)
    {
        $passval = 'passfirst4letter';
    }
    $eg = $passval;

    if(empty($pass)){
        $error = true;
        $passError = "Please enter your password.";
    }

    if (!$error) {
        $stmt = dbconnect()->prepare("SELECT * FROM users WHERE email=:email");
        $stmt->execute(array(
            ":email" => $_SESSION['email'],
        ));
        $row = $stmt->fetchAll();
        $count = $stmt->rowCount();


        if( $count == 1 ) { /* && $passfrmdbffunc==$passfromfunc */
            foreach ($row as  $row)
            {

                //echo $eg;
                $dbpassword = $row['password']; //from db
                //$passfromfunc   = $eg($pass);
                $passfrmdbffunc = $eg($dbpassword);  // fromdb processed
                echo $pass . '<br/>';
                //echo $passfrmdbffunc;

                switch ($passarray)
                {
                    case 0;
                        if ($pass != reversepass($dbpassword))
                        {
                            $errMSG = "Incorrect revese Credentials, Try again...";
                        }
                        else{
                            $_SESSION['logged'] = True;
                            redirect('home.php');
                        }
                    break;
                    case 1:
                        if ($pass != passtoupper($dbpassword))
                        {
                            $errMSG = "Incorrect upper Credentials, Try again...";
                        }
                        else{
                            $_SESSION['logged'] = True;
                            redirect('home.php');
                        }
                    break;
                    case 2;
                        if ($pass != passtolower($dbpassword))
                        {
                            $errMSG = "Incorrect lower Credentials, Try again...";
                        }
                        else{
                            $_SESSION['logged'] = True;
                            redirect('home.php');
                        }
                    break;
                    case 3;
                        if ($pass !== defaultpass($dbpassword))
                        {
                            $errMSG = "Incorrect default Credentials, Try again...";
                        }
                        else{
                            $_SESSION['logged'] = True;
                            redirect('home.php');
                        }
                    break;
                    case 4;
                        if ($pass != passfirst4letter($dbpassword))
                        {
                            $errMSG = "Incorrect 4letter Credentials, Try again...";
                        }
                        else{
                            $_SESSION['logged'] = True;
                            redirect('home.php');
                        }
                    break;
                }

                /*
                if ($passfrmdbffunc == $pass)
                {
                    $_SESSION['logged'] = True;
                    //redirect('home.php');
                }
                else
                {
                    $errMSG = "Incorrect Credentials, Try again...";
                }*/
            }
        } else {
            $errMSG = "Incorrect Credentials, Try again...";
        }

    }

}
?>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Password <?php echo $_SESSION['email']; ?></title>
    <link rel="stylesheet" href="assets/css/bootstrap.min.css" type="text/css"  />
    <link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>

<div class="container">
    <div id="login-form">
        <form method="post" autocomplete="off">
            <div class="col-md-12">
                <div class="form-group">
                    <h2 class="">Provide your password in <?php if (isset($passarray)){echo $passval;}?></h2>
                </div>
                <div class="form-group">
                    <hr />
                </div>
                <?php
                if ( isset($errMSG) ) {
                    ?>
                    <div class="form-group">
                        <div class="alert alert-danger">
                            <span class="glyphicon glyphicon-info-sign"></span> <?php echo $errMSG; ?>
                        </div>
                    </div>
                    <?php
                }
                ?>
                <div class="form-group">

                    <div class="input-group">
                        <span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
                        <input type="password" name="pass" class="form-control" placeholder="Your Password" maxlength="15" />
                    </div>
                    <span class="text-danger"><?php if (isset($passError)) {echo $passError;} ?></span>
                </div>

                <div class="form-group">
                    <hr />
                </div>

                <div class="form-group">
                    <button type="submit" class="btn btn-block btn-primary" name="btn-login">Sign In</button>
                </div>

                <div class="form-group">
                    <hr />
                </div>

                <div class="form-group">
                    <a href="register.php">Sign Up Here...</a>
                </div>

            </div>

        </form>
    </div>

</div>

</body>
</html

我正在使用 PDO-Mysql 驱动程序与数据库进行交互。 哦,随机化密码的 functions.php 代码是:

<?php
function reversepass($password)
{
    return strrev($password);
}

function passtoupper($password)
{
    return strtoupper($password);
}

function passtolower($password)
{
    return strtolower($password);
}

function defaultpass($password)
{
    return $password;
}

function passfirst4letter($password)
{
    return substr($password, 0, 4);
}

function getrandomfunction($password)
{
    $functions = array(reversepass($password),passtoupper($password),passtolower($password),defaultpass($password),passfirst4letter($password));
    return array_rand(array_keys($functions));
}
?>

我的问题是密码表单可能会请求“反向密码”,但是当您反向提供密码时,它不会返回 true,而是返回下一个随机函数的结果。如果返回值为真,我需要它来重定向并设置会话,否则显示错误消息。

编辑 数据库文件有清理功能:

<?php
session_start();
ob_start();


function dbconnect()
{
    $db_host   = '127.0.0.1';
    $db_user   = 'root';
    $dbname    = 'project';
    $db_pass   = '';

    try{
        $connection = new PDO("mysql:host=$db_host;dbname=$dbname",$db_user, $db_pass);
        // set PDO error mode to exception
        $connection->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    }
    catch (PDOException $e){
        echo 'Connection to the database failed ' . $e->getMessage();
    }

    return $connection;
}

function sanitize($data)
{
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);

    return $data;
}

function redirect($url)
{
    header("Location: $url");
}

include_once 'functions.php';
?>

【问题讨论】:

  • 这个方法在哪里? sanitize() 它有什么作用?还是那无关紧要?由于您使用的是准备好的语句,因此无法理解为什么需要其他方法
  • 这是什么类型的应用程序?作为用户,如果被要求输入除我输入的密码以外的任何内容,我会非常恼火
  • function sanitize($data) 你不需要它,也不应该使用它。一个准备好的语句就足够了。
  • @Fred-ii- 我将 dbconnect.php 文件包含在 sanitize 函数中..

标签: php mysql random pdo passwords


【解决方案1】:

您在creds.php 中使用的逻辑不正确。 这就是你现在要做的:

  1. 加载页面 -> 未选择密码验证条件
  2. 用户输入密码 -> 发送表单
  3. 现在您选择了一个随机条件 -> 但它是在用户向您发送密码之后,所以它可能不匹配
  4. 用户收到错误消息和新的密码标准
  5. 用户使用新密码发送表单
  6. 但现在您创建了一个新条件 -> 再次不匹配...

问题是 3 和 6... 因此,解决方案是在显示表单之前创建密码验证条件并将其保存在 SESSION 中以供以后访问。

我会把你的 functions.php 改成这个(简体)

<?php

$PASSWORD_MODES = array(
  "reversepass", "passtoupper", "passtolower", "defaultpass", "passfirst4letter"
);
$RANDOM_MODE = $PASSWORD_MODES[rand(0, count($PASSWORD_MODES)-1)];

function changePasswordByMode($mode, $password) {
    switch ($mode) {
        case "reversepass":
            return strrev($password);
            break;
        case "passtoupper":
            return strtoupper($password);
            break;
        case "passtolower":
            return strtolower($password);
            break;
        case "passfirst4letter":
            return substr($password, 0, 4);
            break;
        case "defaultpass":
            return $password;
            break;
        default:
            return $password;
            break;
    }
}

function validatePasswordMode($original_password, $mode, $test_password) {
    return $test_password === changePasswordByMode($mode, $original_password);
}

?>

这是creds.php(简体):

<?php
require_once 'dbconnect.php';
/*
  SET VARS
 */
$error = $pass = $errMSG = $passError = false;
global $RANDOM_MODE;
/*
  CHECK POST FOR $pass
 */
if (isset($_POST['pass'])) {
  $pass = sanitize($_POST['pass']);
  if(empty($pass)){
    $error = true;
    $passError = "Please enter your password.";
   }
}
/*
  IF $pass IS PROVIDED & $_SESSION["passmode"] IS SET -> VALIDATE
 */
if ($pass && isset($_SESSION["passmode"])) {
  $stmt = dbconnect()->prepare("SELECT * FROM users WHERE email=:email");
  $stmt->execute(array(
    ":email" => $_SESSION['email'],
  ));
  $row = $stmt->fetchAll();
  $count = $stmt->rowCount();

  if ($count == 1 ) {
    $dbpassword = $row[0]['password'];

    $VALID_PASS = validatePasswordMode(
      $row[0]['password'], 
      $_SESSION["passmode"],
      $test_password);

    if ($VALID_PASS) {
      $_SESSION['logged'] = TRUE;
      redirect('home.php');
    } else {
      $error = true;
      $errMSG = "Incorrect credentials. Try again...";
    }
  } // endif $count
} // endif $pass && isset($_SESSION["passmode"]))
/*
  SET PASSMODE
*/
$_SESSION["passmode"] = $RANDOM_MODE;
// 
?>
<!-- in your HTML change this part: -->
<div class="form-group">
  <h2 class="">
    Provide your password in <?php echo $_SESSION["passmode"]; ?>
  </h2>
</div>
<!-- keep the rest -->

【讨论】:

    猜你喜欢
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 2021-09-22
    • 2015-04-19
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    相关资源
    最近更新 更多