首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用PHP和PDO将密码重置发送到电子邮件的登录系统

使用PHP和PDO将密码重置发送到电子邮件的登录系统
EN

Code Review用户
提问于 2018-11-24 02:53:27
回答 1查看 1.2K关注 0票数 2

我非常喜欢使用PDO,因为它很简单,很容易生成一个安全的查询,我准备了所有的查询和占位符,我认为它是安全的,但我一点也不确定,我在想我是否正确地使用了trim()。你们怎么想?如果有任何疑问,请在评论部分问我。

login.php

代码语言:javascript
复制
prepare($Query);
  $statement->bindValue(':email', $email);
  $statement->execute();
  $user = $statement->fetch(PDO::FETCH_ASSOC);    
  $RowCount = $statement->rowCount();
} catch (PDOerrorInfo $e){}

  if( $RowCount == 0 ){
   // User doesn't exist
    $_SESSION['message'] = "Não existe um usuário com este e-mail.";
    header("location: error.php");

  } else{ // User exists

      if( password_verify($_POST['password'], $user['password'])){
        $_SESSION['email']  = $user['email'];
        $_SESSION['first_name'] = $user['first_name'];
        $_SESSION['last_name'] = $user['last_name'];
        $_SESSION['username'] = $user['username'];
        $_SESSION['img'] = $user['img'];
        $_SESSION['active'] = $user['active'];
        $_SESSION['logged_in'] = true;
        header("location: ../index.php");
      } else {
          $_SESSION['message'] = "Senha incorreta, tente novamente!";
          header("location: error.php");
        }      
    }  
}

register.php

代码语言:javascript
复制
prepare("SELECT * FROM users WHERE email = :email");
$result->bindParam(':email', $email);
$result->execute();
$RowCount = $result->rowCount();

if ( $RowCount > 0 ) { 
    $_SESSION['message'] = 'Já existe um usuário com este e-mail!';
    header("location: error.php");   
} else {
    $sql = "INSERT INTO users (first_name, last_name, username, img, email, password, hash) VALUES (:first_name, :last_name, :username, :img, :email, :password, :hash)";
    $sql = $conn->prepare($sql);
    $sql->bindParam(':first_name', $first_name);
    $sql->bindParam(':last_name', $last_name);
    $sql->bindParam(':username', $username);
    $sql->bindParam(':img', $img);
    $sql->bindParam(':email', $email);
    $sql->bindParam(':password', $password);
    $sql->bindParam(':hash', $hash);
    $sql->execute();

}

forgot.php

代码语言:javascript
复制
prepare("SELECT * FROM users WHERE email = :email");
    $result->bindValue(':email', $email);
    $result->execute();
    $RowCount = $result->rowCount();

    if ( $RowCount == 0 )
    { 
        $_SESSION['message'] = "Não existe um usuário com este e-mail.";
        header("location: error.php");
    }
    else {
        $user = $result->fetch(PDO::FETCH_ASSOC);      
        $email = $user['email'];
        $hash = $user['hash'];
        $first_name = $user['first_name'];

        $_SESSION['message'] = "Link de confirmação enviado para $email"
        . " clique no link para resetar a sua senha!";

        $to      = $email;
        $subject = 'Resetar senha - AnimeFire';
        $message_body = '
        Olá '.$first_name.' :),

        Você solicitou o resete de sua senha.

        Clique no link para resetar:

        https://localhost/login-system/reset.php?email='.$email.'&hash='.$hash;  

        mail($to, $subject, $message_body);

        header("location: success.php");
  }
}
?>

reset.php

代码语言:javascript
复制
prepared("SELECT * FROM users WHERE email = :email AND hash = :hash");
    $result->bindValue(':email', $email);
    $result->bindValue(':hash', $hash);
    $result->execute();
    $RowCount = $result->rowCount();

    if ( $RowCount == 0 )
    { 
        $_SESSION['message'] = "A conta já foi verificada ou o URL é inválido!";
        header("location: error.php");
    }
}else {
    $_SESSION['message'] = "A verificação falhou :/ tente novamente!";
    header("location: error.php");  
}
?>

reset_password.php

代码语言:javascript
复制
prepare("UPDATE users SET password = :new_password, hash = :hash WHERE email = :email");
        $sql->bindValue(':new_password', $new_password);
        $sql->bindValue(':hash', $hash);
        $sql->bindValue(':email', $email);
        $sql->execute();

        if ( $conn->prepare($sql) ) {

        $_SESSION['message'] = "Sua senha foi resetada com sucesso ^^";
        header("location: success.php");    

        }
    } else {
        $_SESSION['message'] = "As senhas não estão iguais, tente novamente!";
        header("location: error.php");    
    }
}
?>

profile.php

代码语言:javascript
复制
Nome: 
Email: 
EN

回答 1

Code Review用户

回答已采纳

发布于 2018-11-24 13:21:04

trim()函数的用法是可以的。

这里最大的问题是散列安全性。永久的md5( rand(0,1000) );散列不是安全性。它是如此容易猜测,以至于你可以计算它根本不存在。

每次新的请求都会生成密码提醒散列。它应该是一些不可预测的东西,例如http://php.net/manual/en/function.random-bytes.php

其他问题非常常见,它们被列入了我的十大PHP妄想清单:

在reset_password.php中也有一个奇怪的代码片段,检查准备测试上一个查询的成功的结果是没有意义的。此外,考虑到您的错误报告是正确的,没有必要检查是否成功,只需立即重定向:

代码语言:javascript
复制
  $sql->bindValue(':email', $email);
  $sql->execute();
  $_SESSION['message'] = "Sua senha foi resetada com sucesso ^^";
  header("location: success.php");    
  exit;

在代码中的每个位置头调用之后总是添加exit也是一个很好的习惯,因为标头本身并不意味着代码执行已经停止。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/208319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档