【问题标题】:How to send an email with a link to reset password in PHP如何发送带有链接的电子邮件以在 PHP 中重置密码
【发布时间】:2019-04-04 14:21:38
【问题描述】:

我喜欢通过 my website 探索 PHP 的世界,通过创建个人小项目,让我了解当前和未来的工作经验......

当用户在我的网站上创建帐户时,我会尽快添加电子邮件信息...

经过几个小时的研究和阅读,我无法找到或理解如何发送带有重置用户密码链接的电子邮件...

这是我的哈希方法:

$options = ['cost' => 11, 'salt' => random_bytes(22)];
$passwordCrypter = password_hash($password, PASSWORD_BCRYPT, $options);

我认为我们需要使用这种方法,因为我认为不建议解密密码...

但是为什么……我想明白……

谢谢

祝大家开心

【问题讨论】:

  • 不要解密密码,对用户输入进行哈希处理并将该哈希值与数据库中的哈希值进行比较
  • 我认为您应该在电子邮件中发送重置密码链接,您可以在重置表单提交时设置新密码。仅供参考:salt 已弃用 >=PHP 7.0.0
  • 你的问题太宽泛了,你需要缩小范围。并且密码被散列的方式,不应该对你的密码重置机制做任何事情。
  • 生成一个随机字符串,存储在数据库中,并用作激活帐户链接的一部分,例如example.com/…
  • passhword_hash() php 中的函数无法解密。您可以使用用户的id 来使用GET 方法并更新特定用户的密码。使用更新密码机制给出接受 GET 值的文件的链接。您还可以在 php 中使用base64encode() 来隐藏 id 以防止出现在 url 中。

标签: php sendmail reset-password


【解决方案1】:

不推荐解密密码

如果理论上甚至可以解密您的密码,那么您做错了。

此外,根据您的描述,如果您允许匿名更改密码,您将创建一个容易被利用的拒绝服务漏洞。正确的解决方案是:

  • 当有人声明身份并请求重置密码时,生成具有高冗余和有限 TTL 的令牌,通过电子邮件将其发送给用户。请勿更改密码。

  • 当重置令牌与用户名一起出现时,验证 TTL 未过期并且令牌已颁发给声明的用户名,然后允许用户选择新密码。

    李>

【讨论】:

  • 感谢信息,我明白不推荐也不会使用它...我将使用发送邮件的方式更改密码关联链接+用户的链接跨度>
【解决方案2】:

在此处使用 PHPMailer 我的代码示例其中 $dir 是您的当前目录

function mailSet($to,$full_name,$subject,$body){
    require($dir.'vendor/mailer/PHPMailerAutoload.php');
    require($dir.'vendor/mailer/class.phpmailer.php');

    $mail = new PHPMailer();
    $mail->IsSMTP();
    $mail->Host = 'YOUR HOST';
    $mail->SMTPAuth = TRUE;

    $mail->Username = 'HOST EMAIL ACCOUNT'; 
    $mail->Password = 'HOST PASSWORD'; 

    $mail->From = 'FROM EMAIL';
    $mail->setFrom('FROM EMAIL', 'FULL NAME');

    $mail->AddAddress($to, $full_name);
    $mail->WordWrap = 70;

    $mail->Subject = $subject;
    $mail->Body = $body;

    $mail->IsHTML(TRUE);


    if(!$mail->Send()){
      echo 'SEND';
    } else {
     echo 'FAILED TO SEND';        }
}

function forgetPassword($account){
  global $dir;
  $data=getData('users',$account); //GET DATA FROM DATABASE
  $link=getDataBy('forget_password','account',$data['id']); //RELATION DATA FROM TABLE USERS
  $body='SOME TEXT <p>YOU CAN USE HTML TAG TO <a href="'.$dir.'login/changepassword?SESSION_ID='.$link['link'].'&&SESSION_VALID='.md5(rand(0,100)).'">LINK TO CLICK</a><p>END OF HTML TAG</p>';
  return $body;
}`

使用 PHPMailer 的 PHP 邮件示例,其中 $to = 收件人电子邮件,$full_name = 收件人全名,$subject = 电子邮件主题,$body = EMAIL HTML 正文

【讨论】:

    【解决方案3】:
    <html>
      <body>
        <form method="post" action="send_link.php">
          <p>Enter Email Address To Send Password Link</p>
          <input type="text" name="email">
          <input type="submit" name="submit_email">
        </form>
      </body>
    </html>
    

    步骤1.制作一个HTML文件并为密码重置系统定义标记

    <?php
    if(isset($_POST['submit_email']) && $_POST['email'])
    {
      mysql_connect('localhost','root','');
      mysql_select_db('sample');
      $select=mysql_query("select email,password from user where email='$email'");
      if(mysql_num_rows($select)==1)
      {
        while($row=mysql_fetch_array($select))
        {
          $email=md5($row['email']);
          $pass=md5($row['password']);
        }
        $link="<a href='www.samplewebsite.com/reset.php?key=".$email."&reset=".$pass."'>Click To Reset password</a>";
        require_once('phpmail/PHPMailerAutoload.php');
        $mail = new PHPMailer();
        $mail->CharSet =  "utf-8";
        $mail->IsSMTP();
        // enable SMTP authentication
        $mail->SMTPAuth = true;                  
        // GMAIL username
        $mail->Username = "your_email_id@gmail.com";
        // GMAIL password
        $mail->Password = "your_gmail_password";
        $mail->SMTPSecure = "ssl";  
        // sets GMAIL as the SMTP server
        $mail->Host = "smtp.gmail.com";
        // set the SMTP port for the GMAIL server
        $mail->Port = "465";
        $mail->From='your_gmail_id@gmail.com';
        $mail->FromName='your_name';
        $mail->AddAddress('reciever_email_id', 'reciever_name');
        $mail->Subject  =  'Reset Password';
        $mail->IsHTML(true);
        $mail->Body    = 'Click On This Link to Reset Password '.$pass.'';
        if($mail->Send())
        {
          echo "Check Your Email and Click on the link sent to your email";
        }
        else
        {
          echo "Mail Error - >".$mail->ErrorInfo;
        }
      } 
    }
    ?>
    

    步骤2.制作一个PHP文件来发送链接

    <?php
    if($_GET['key'] && $_GET['reset'])
    {
      $email=$_GET['key'];
      $pass=$_GET['reset'];
      mysql_connect('localhost','root','');
      mysql_select_db('sample');
      $select=mysql_query("select email,password from user where md5(email)='$email' and md5(password)='$pass'");
      if(mysql_num_rows($select)==1)
      {
        ?>
        <form method="post" action="submit_new.php">
        <input type="hidden" name="email" value="<?php echo $email;?>">
        <p>Enter New password</p>
        <input type="password" name='password'>
        <input type="submit" name="submit_password">
        </form>
        <?php
      }
    }
    ?>
    

    步骤3.制作一个PHP文件来重置密码

    <?php
    if(isset($_POST['submit_password']) && $_POST['key'] && $_POST['reset'])
    {
      $email=$_POST['email'];
      $pass=$_POST['password'];
      mysql_connect('localhost','root','');
      mysql_select_db('sample');
      $select=mysql_query("update user set password='$pass' where email='$email'");
    }
    ?>
    

    步骤4.制作一个PHP文件来更新新密码

    【讨论】:

    • 抱歉,这里的一切都是错误的:Sql 注入、纯文本密码(或 md5,也好不了多少)、已弃用(在 php 7+ 中不存在)mysql_* 函数,等等
    • 是的先生,你是对的,但我认为 md5() 有利于加密,因为它在 php 中不可解密
    • 你用md5()替换了一个可靠的散列工具?为什么?
    • "non decryptable in php" - 你不了解问题域。你可以通过阅读彩虹表、扩展攻击和加盐来解决这个问题。
    • 我的所有输入都受此方法保护:$patternUser = "#^[0-9a-z]([0-9a-z]{0,13})[0-9a-z]$#"; if (!preg_match($patternUser, $champInitial['user'])) { $champInitial['champInvalid'] = true;
    猜你喜欢
    • 2016-04-04
    • 2019-11-28
    • 2014-02-08
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 2012-08-10
    相关资源
    最近更新 更多