Php 恢复密码

Php 恢复密码,php,pdo,Php,Pdo,我试图通过向用户发送一封电子邮件,其中包含一个可以更改密码的页面链接,来增加用户恢复密码的能力。我在数据库中添加了一个名为recover的新表,其中包含id、user_id、key和created字段,当他们向想要恢复密码的帐户输入电子邮件时,我在recover表中添加了一行。然后,我向输入的电子邮件发送一封电子邮件,其中包含一个页面链接,他们应该在该页面上输入新密码 我的问题是,为什么即使更改了密码,恢复表中的行也不会被删除 这是我的代码: recover.php: <?php requ

我试图通过向用户发送一封电子邮件,其中包含一个可以更改密码的页面链接,来增加用户恢复密码的能力。我在数据库中添加了一个名为recover的新表,其中包含id、user_id、key和created字段,当他们向想要恢复密码的帐户输入电子邮件时,我在recover表中添加了一行。然后,我向输入的电子邮件发送一封电子邮件,其中包含一个页面链接,他们应该在该页面上输入新密码

我的问题是,为什么即使更改了密码,恢复表中的行也不会被删除

这是我的代码:

recover.php:

<?php
require_once 'core/init.php';

$user = new User();
if ($user->isLoggedIn()) {
    Redirect::to('index.php');
}

if (isset($_GET['success']) === true && empty($_GET['success']) === true) {
?>
    <!-- Create your message -->
    <p>We've emailed you</p>
<?php
} else if (isset($_GET['key']) === true && empty($_GET['key']) === false) {

    $key = $_GET['key'];
    $userInfo = $user->get_user_by_key($key);

    if (!$userInfo) {
        echo 'user not found';
        //prompt to resend link
    } else {
        //display change password form
        //session_start();
        $_SESSION['user_id'] = $userInfo['user_id'];
        $_SESSION['key'] = $key;
?>
        <div class="page-content">

            <form action="" method="post">
                <h1>Change password</h1>
                <div class="inset">
                <?php
                if (Input::exists()) {
                    if (Token::check(Input::get('token'))) {

                        $validate = new Validate();
                        $validation = $validate->check($_POST, array(
                            'password' => array(
                                'alias' => 'Password',
                                'required' => true,
                                'min' => 6
                            ),
                            'password_again' => array(
                                'alias' => 'Password confirmation', // <--- using the alias
                                'required' => true,
                                'min' => 6,
                                'matches' => 'password'
                            )
                        ));

                        if ($validation->passed()) {

                            $salt = Hash::salt(100);

                            session_start();
                            if(isset($_POST['password'], 
                                     $_POST['password_again'], 
                                     $_SESSION['user_id'], 
                                     $_SESSION['key'])){

                                if ($_POST['password'] === $_POST['password_again']) {
                                    //password should be hashed
                                    $password = Hash::make(Input::get('password'), $salt);
                                    $success = $user->update_user_password($password, $salt, $_SESSION['user_id']);

                                    if ($success) {
                                        $user->delete_key($_SESSION['key']);
                                    } else {
                                        //failed to update password
                                    }
                                } else {
                                    echo 'Password not matching';
                                }
                            }

                            Session::flash('home', 'Your password has been changed');
                            Redirect::to('index.php');


                        } else {
                            foreach ($validation->errors() as $error) {
                                echo '<i class="fa fa-exclamation-triangle"></i>&nbsp;&nbsp;', $error, '<br>';
                                echo '<br />';
                            }
                        }
                    }
                }
                ?>

                <p>
                    <label for="password">PASSWORD</label>
                    <input type="password" name="password" id="password" required>
                </p>
                <p>
                    <label for="password_again">CONFIRM PASSWORD</label>
                    <input type="password" name="password_again" id="password_again" required>
                </p>
                </div>

                <input type="hidden" name="token" value="<?php echo Token::generate(); ?>">
                <p class="p-container">
                    <input type="submit" name="go" id="go" value="Change password">
                </p>

            </form>
        </div>
<?php   
    }

} else {

    $mode_allowed = array('username', 'password');

    if (isset($_GET['mode']) === true && in_array($_GET['mode'], $mode_allowed) === true) {
        if (isset($_POST['email']) === true && empty($_POST['email']) === false) {
            $email = Input::get('email');
            $result = $user->emailExists($email);

            if (!$result) {
                //Your custom error saying that that email does not exist
                echo 'That email does not exist';
            } else {
                $user->recover($_GET['mode'], $email);
                Redirect::to('recover.php?success');
            }
        }
    ?>
        <form action="" method="post">
            <ul>
                <li>
                    Please enter your email address:<br>
                    <input type="text" name="email" placeholder="Enter Email">
                </li>
                <li><input type="submit" class="sub-btn tx-shadow" value="Recover"></li>
            </ul>
        </form>

    <?php
    } else {
        Redirect::to('index.php');
    }
}
    public function emailExists($email){
    $sql = "SELECT *
            FROM `users`
            WHERE `email` = ?
    ";
    $data =  $this->_db->query_single($sql, array($email));
    return $data;
}
public function recover($mode, $email) {

    //Get data of user
    $user_data = $this->getUserByEmail($email);
    // Email User

    if ($mode == 'username') {
        $this->sendActivation($email, 'Your Username', 'Hello'.$user_data['username']. '\n\nYour username is: '.$user_data['username'].'\n\nThank you\nBusarna');
    } else if ($mode == 'password') {
        $key = substr(sha1(rand(999, 999999)), 0, 10);
        //update password
        $this->_db->insert('recover', array(
            'user_id' => $user_data['id'],
            'key' => $key,
            'created' => date('Y-m-d H:i:s')
        ));
        //email user password link
        $this->sendActivation($email, 'Your Password', 'Hello'.$user_data['username']. '\n\nClick <a href="localhost/website/recover.php?key='.$key.'">here</a> to change your password\n\nThank you\nBusarna');
    }
}

public function getUserByEmail($email) {
    $sql = "SELECT *
            FROM `users`
            WHERE `email` = ?
            ";

    $result = $this->_db->query_single($sql, array($email));

    return $result;
}

public function get_user_by_key($key) {
    $sql = "SELECT *
            FROM `recover`
            WHERE `key` = ?
            ";

    $result = $this->_db->query_single($sql, array($key));

    return $result;
}

public function delete_key($key) {
    $sql = "DELETE
            FROM `recover`
            WHERE `key` = ?
            ";
    //replace with your delete function
    $result = $this->_db->query_single($sql, array($key));

    return $result;
}


public function update_user_password($password, $salt, $user_id) {
    $sql = "UPDATE users
            SET `password`= ?,
                `salt` = ?
            WHERE `id`= ?";
    //replace with your update function
    $result = $this->_db->query_single($sql, array($password, $salt, $user_id));

    return $result;
}
public function query($sql, $params = array()) {
    $this->_error = false;
    if($this->_query = $this->_pdo->prepare($sql)) {
        $x = 1;
        if(count($params)) {
            foreach ($params as $param) {
                $this->_query->bindValue($x, $param);
                $x++;
            }
        }

        if ($this->_query->execute()) {
            $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
            $this->_count = $this->_query->rowCount();
        } else {
            $this->_error = true;
        }
    }

    return $this;
}

public function query_single($sql, $params = array()) {
    $this->_error = false;
    if($this->_query = $this->_pdo->prepare($sql)) {
        $x = 1;
        if(count($params)) {
            foreach ($params as $param) {
                $this->_query->bindValue($x, $param);
                $x++;
            }
        }

        if ($this->_query->execute()) {
            $this->_results = $this->_query->fetch(PDO::FETCH_ASSOC);
            $this->_count = $this->_query->rowCount();
        } else {
            $this->_error = true;
        }
    }

    return $this->_results;
}
如果你们还需要什么帮助,请告诉我

有人知道我该怎么继续吗?谢谢你的帮助

提前感谢,


布萨纳

你走在正确的轨道上,你只需要更多的逻辑:

public function get_user_by_key($key) {
    $sql = "SELECT *
            FROM `recover`
            WHERE `key` = ?
            ";

    $result = $this->_db->query_single($sql, array($key));

    return $result;
}


public function delete_key($key) {
    $sql = "DELETE
            FROM `recover`
            WHERE `key` = ?
            ";
    //replace with your delete function
    $result = $this->_db->query_single($sql, array($key));

    return $result;
}


public function update_user_password($password, $user_id) {
    $sql = "UPDATE Customers
            SET `password`= ?
            WHERE `user_id`=?";
    //replace with your update function
    $result = $this->_db->query_single($sql, array($password, $user_id));

    return $result;
}
您可以按以下方式使用该函数:

if(isset($_GET['key'])){
    $key = $_GET['key'];
    $user = get_user_by_key($key);

    if(!$user){
        echo 'user not found';
        //prompt to resend link
    }else{
        //display change password form
        session_start();
        $_SESSION['user_id'] = $user['user_id'];
        $_SESSION['key'] = $key;
    }
}
然后,当用户发布信息时,请执行以下操作:

session_start();
if(isset($_POST['password'], 
         $_POST['password_confirmation'], 
         $_SESSION['user_id'], 
         $_SESSION['key'])){

    if($_POST['password'] === $_POST['password_confirmation']){
        //password should be hashed
        $success = update_user_password($password, $_SESSION['user_id']);

        if($success){
            delete_key($_SESSION['key']);
        }else{
            //failed to update password
        }
    }else{
        echo 'Password not matching';
    }
}

指定您遇到的问题。不需要输入完整的代码。在你的终端调试,如果发现问题,把它放在这里。“通过给他们发送一封带有临时密码的电子邮件”-请不要,这只是一个网站可能具有的最糟糕的可用性,但大多数网站都这样做。您只需向他们发送一个表单链接,他们可以在其中更改密码。对用户来说,它同样安全,而且更舒适。我该怎么做@ThiefMaster我被困在恢复函数中,我在其中注释了更新密码您应该生成一个令牌并将其存储在服务器端。你发送了一个包含该令牌的链接。只有一个请求引用了有效的(现有的和最近的)令牌,那么密码更改是允许的。我编辑了这个问题,需要帮助来实现您的想法,我不知道如何使恢复功能安全@ThiefMasterI添加了您的代码,几乎所有的工作都正常:)我添加了stackoverflow上的代码。我现在可以恢复密码,但是,恢复表中的行不会被删除@meda@Busarna4别忘了批准答案!!;)