【问题标题】:Password Reset Link : "TO" email address not working密码重置链接:“TO”电子邮件地址不起作用
【发布时间】:2015-05-10 19:25:07
【问题描述】:

我在 PHP 中创建了密码重置功能。

它工作得很好............除了,由于某种原因,我无法设置收件人的电子邮件地址:“TO

代码是这样工作的:

(a) 要求用户提供他的登录名/用户名 (b) php 向数据库发送一个 sql 查询; (c) 如果找到用户名,php 获取电子邮件地址,并通过电子邮件发送重置链接 (d) 此重置链接附有一个独特的“令牌” (e) 用户点击其电子邮件中的链接,并被重定向到他重置密码的新页面

一切正常............除了电子邮件结构本身。电子邮件包括:TO、CC、SUBJECT、BODY 和 HEADERS

一切都在显示............除了实际的“TO”。

事实上,我知道代码有效的唯一原因是我通过“CC”获得了电子邮件的副本

这是我的代码:

  if(isset($_POST['submit'])) {

  $login = $_POST['login'];

  $query = "select * from personal_data where login='$login'";
  $result = mysqli_query($conn,$query);
  $count=mysqli_num_rows($result);
  $rows=mysqli_fetch_array($result);


  if($count==0) {

 echo "Sorry; that username does not exist in our database";
 }

else {

 function getRandomString($length) 
   {
$validCharacters = "ABCDEFGHIJKLMNPQRSTUXYVWZ123456789!#+=%&/?*$";
$validCharNumber = strlen($validCharacters);
$result = "";

for ($i = 0; $i < $length; $i++) {
    $index = mt_rand(0, $validCharNumber - 1);
    $result .= $validCharacters[$index];
 }
 return $result;    }

$token=getRandomString(40);
$q="insert into token (token,login) values ('".$token."','".$login."')";
mysqli_query($conn,$q);

function mailresetlink($to,$token){

$to = $rows['email'];
$subject = "Password Reset";
$uri = 'http://'.$_SERVER['HTTP_HOST'] ;
$message = '
<html>
<head>
<title>Password Reset Link</title>
</head>
<body>
<p>We received a Password-Reset request from your account.</p>
<p>Click on the following link to reset your password : <a   
href="'.$uri.'/PHP/password_reset?token='.$token.'">Reset Password</a></p>
</body>
</html>
 ';
 $headers = "MIME-Version: 1.0" . "\r\n";
 $headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
 $headers .= 'From: Support<support@xxxxx.com>' . "\r\n";
 $headers .= 'Bcc: Info<info@xxxxx.com>' . "\r\n";

 if(mail($to, $subject, $message, $headers))     {

  echo "A password reset link has been sent to your email address."

    }
 }

 if(isset($_POST['login'])) { 
    mailresetlink($email,$token);

    exit();
            } 

     }
  }

【问题讨论】:

  • 危险:你很容易受到SQL injection attacks的影响,你需要defend你自己。
  • 在打开 PHP 标记后立即将错误报告添加到文件顶部,例如 &lt;?php error_reporting(E_ALL); ini_set('display_errors', 1);,然后是其余代码,以查看它是否产生任何结果,以及 @987654325 @到mysqli_query()
  • 你只是完全覆盖了你的问题。这应该作为一个新问题提出。请回滚到您的原始帖子,否则我会因此而被否决。
  • 如何回滚?顺便说一句,我找到了错误的原因:每当生成新令牌时,令牌和用户名(登录名)都会输入到数据库表“令牌”中。好吧,在我更改代码后,登录不再被发送到数据库表。只是令牌。
  • 没关系,我把你的问题回滚到原帖了。这不是在 Stack 上做事的方式。你的新问题应该是一个新问题,而我的回答解决了原来的问题。另外,请在我的回答中查看我的评论,了解可能出了什么问题。

标签: php email mail-form


【解决方案1】:

您的代码无法正常工作的原因有几个原因。

其中之一是$rows 需要驻留在function mailresetlink($to,$token) 函数的参数中。

将其更改为 function mailresetlink($to,$token,$rows) 并对内部的 if(isset($_POST['login'])){...} 执行相同操作

if(isset($_POST['login'])) { 
    mailresetlink($email,$token,$rows);

    exit();
            } 

另外,如果不是拼写错误或粘贴错误;此行中还缺少一个分号:

echo "A password reset link has been sent to your email address."
                                                                 ^ right there

完成上述所有操作后,在我的测试期间成功将所有信息发送到电子邮件。


旁注:您当前的代码对SQL injection 开放。使用mysqli with prepared statementsPDO with prepared statements它们更安全

【讨论】:

  • 工作出色!谢谢,弗雷德。哦,顺便说一句,关于 SQL 注入问题,我假设您的意思是执行以下操作: $login = mysqli_real_escape_string($conn, $_POST['login']); ??
  • @phpnewbie2015 不客气,很高兴知道我能够提供帮助。至于注射,是的,这是一个开始。您还可以查看 XSS 注入。这里有几篇关于主题en.wikipedia.org/wiki/Cross-site_scriptingowasp.org/index.php/Cross-site_Scripting_%28XSS%29的文章
  • 再次感谢 Fred )))))))))) 真的很感激。
  • 呃-哦。出了点问题。 ((((电子邮件正在发送。但是............“令牌”未附加到链接。(((((()我做了两件事:(a)我复制了您的代码(在 if 块之后移动了 getRandomString 和 mailresetlink)............并且“令牌”不再附加到重置链接(b)我回到使用我之前的格式(即,在“if”块之前保留getRandomString和mailresetlink............并且附加了“token”。但是............它从来没有工作过。
  • 当我点击电子邮件中的重置密码链接时,我总是收到:链接无效,或者密码已被更改。 (如果重置链接已经被使用过一次,这就是应该发生的事情)。我已经更新了我的原始帖子以显示完整的代码(正如你向我建议的那样)。
【解决方案2】:

您不能在 if 或 while 或任何范围内定义函数。在您打算使用它们之前或之后定义它们。试试下面的代码:

<?php
if ( isset($_POST['submit']) ) {

    $login = $_POST['login'];
    $email = $_POST['email'];


    $query = "select * from personal_data where login='$login'";
    $result = mysqli_query($conn, $query);
    $count = mysqli_num_rows($result);
    $rows = mysqli_fetch_array($result);


    if ($count == 0) {

        echo "Sorry; that username does not exist in our database";
    } else {


        if (isset($_POST['login'])) {
            mailresetlink($email, $token, $rows);

            exit();
        }

    }
}

function getRandomString($length)
{
    $validCharacters = "ABCDEFGHIJKLMNPQRSTUXYVWZ123456789!#+=%&/?*$";
    $validCharNumber = strlen($validCharacters);
    $result = "";

    for ($i = 0; $i < $length; $i++) {
        $index = mt_rand(0, $validCharNumber - 1);
        $result .= $validCharacters[$index];
    }
    return $result;
}

$token = getRandomString(40);
$q = "insert into token (token,login) values ('" . $token . "','" . $login . "')";
mysqli_query($conn, $q);

function mailresetlink($to, $token, $rows)
{

    $to = $rows['email'];
    $subject = "Password Reset";
    $uri = 'http://' . $_SERVER['HTTP_HOST'];
    $message = '
        <html>
        <head>
            <title>Password Reset Link</title>
        </head>
        <body>
        <p>We received a Password-Reset request from your account.</p>

        <p>Click on the following link to reset your password : <a
                href="' . $uri . '/PHP/password_reset?token=' . $token . '">Reset Password</a></p>
        </body>
        </html>
        ';
    $headers = "MIME-Version: 1.0" . "\r\n";
    $headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
    $headers .= 'From: Support <support@xxxxx.com>' . "\r\n";
    $headers .= 'Bcc: Info <info@xxxxx.com>' . "\r\n";

    if (mail($to, $subject, $message, $headers)) {

        echo "A password reset link has been sent to your email address.";

    }
}
?>

另外,请注意 Quentin 关于防止 SQL 注入的建议。

我所做的是:

  • getRandomStringmailresetlink 移到if 块之后
  • mailresetlink函数添加了参数$rows,因此它可以找到$rows变量的使用(超出范围)

你还需要定义$email,因为它没有在任何地方设置,所以我为你做了(我猜你在某处还有一个名称为email的输入字段。

测试一下,应该可以了。

【讨论】:

  • 最好仔细检查这个'/PHP/password_reset?token=' . $token . ',因为mailresetlink()函数中的exit();,加上$token = getRandomString(40);也需要进入里面function mailresetlink($to, $token, $rows){...}
猜你喜欢
  • 1970-01-01
  • 2011-04-16
  • 2016-04-18
  • 2021-02-05
  • 2021-01-05
  • 1970-01-01
  • 2020-05-19
  • 2018-09-10
  • 2012-02-03
相关资源
最近更新 更多