如何防止phpmailer发送的带有GET参数的链接被另一个文件读取

如何防止phpmailer发送的带有GET参数的链接被另一个文件读取,php,get,phpmailer,unlink,Php,Get,Phpmailer,Unlink,对于一个简单的邮件列表,我使用phpmailer向订阅者发送一条带有“unsubscribe链接”的消息。链接中有GET参数。 我还有一个取消订阅订户的文件:unsubscribe.php。 我用unsubscribe链接发送电子邮件的文件名为admin.php。两个文件位于同一目录中 这是我如何使用Unsubsibe链接(admin.php)发送电子邮件的部分代码: $mail->AddAddress($recipients\u email,$recipients\u name)//添加“收件

对于一个简单的邮件列表,我使用phpmailer向订阅者发送一条带有“unsubscribe链接”的消息。链接中有GET参数。 我还有一个取消订阅订户的文件:
unsubscribe.php
。 我用unsubscribe链接发送电子邮件的文件名为
admin.php
。两个文件位于同一目录中

这是我如何使用Unsubsibe链接(admin.php)发送电子邮件的部分代码:

$mail->AddAddress($recipients\u email,$recipients\u name)//添加“收件人”地址
//使用“取消订阅”链接发送电子邮件
试一试{
$mail->Body=$\u POST[“message”]。

; $mail->Send(); $result='发送给订阅方的新闻稿:'.$recipients_category'; }捕获(例外$e){ $result='Mailer Error('.htmlspecialchars($recipients_email)。'.$mail->ErrorInfo'; $mail->smtp->reset();//重置smtp连接 } $mail->clearAddresses();//清除下一次迭代的所有地址
我的unsubscribe.php如下所示:

$id = $_GET['id'];
$email = $_GET['email'];
// decode the id and email string
$id_decode = base64_decode(urldecode($id));
$email_decode = base64_decode(urldecode($email));

$url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
if ( parse_url($url, PHP_URL_QUERY) != NULL ) { // check if there is a url string with name and email               
    $filename = 'subscribers/'.$id_decode.'.txt';   
    // delete subscribers entry
    if(file_exists($filename)) { 
        unlink($filename);  
        echo '<div class="alert alert-success"><b>'.$email_decode.'</b> is successfully removed from our mailinglist!</div>';       
    }
    else {
        echo '<div class="alert alert-danger">Email not found or you already have unsubscribed from our mailinglist!</div>';
    }       
}
$id=$\u GET['id'];
$email=$_获取['email'];
//解码id和电子邮件字符串
$id_decode=base64_decode(urldecode($id));
$email_decode=base64_decode(urldecode($email));
$url=“http://$\u服务器[http\u主机]$\u服务器[REQUEST\u URI]”;
if(parse_url($url,PHP_url_QUERY)!=NULL){//检查是否有包含名称和电子邮件的url字符串
$filename='subscribers/'。$id_decode..txt';
//删除订阅服务器条目
如果(文件_存在($filename)){
取消链接($filename);
echo“”。$email_decode.'已成功从我们的邮件列表中删除!';
}
否则{
echo“未找到电子邮件,或者您已取消订阅我们的邮件列表!”;
}       
}
发生了什么:出于某种奇怪的原因,每次我向订户发送电子邮件时,
unsubscribe.php
从列表中取消订阅服务器的链接。 而unsubscribe.php文件仅在有人单击电子邮件中的链接时使用

我在删除文件
unsubscribe.php
时发现了这一点。如果我再发送一封电子邮件,订阅者将不再被解除链接。 如果我只发送邮件正文中的信息而不发送链接,订户也不会被删除!因此,问题在于链接与unsubscribe.php文件的组合

我怎样才能防止呢

根据这一点:

这可以解决您的问题:

$id = $_GET['id'];
$email = $_GET['email'];
// decode the id and email string
$id_decode = base64_decode(urldecode($id));
$email_decode = base64_decode(urldecode($email));

if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
    if (strtolower(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) != strtolower($_SERVER['HTTP_HOST'])) {

/* ALL CODE BELOW WILL BE EXECUTED IF NOT FROM YOUR OWN SERVER*/
        $filename = 'subscribers/'.$id_decode.'.txt';   
        // delete subscribers entry
        if(file_exists($filename)) { 
            unlink($filename);  
            echo '<div class="alert alert-success"><b>'.$email_decode.'</b> is successfully removed from our mailinglist!</div>';       
        }
        else {
            echo '<div class="alert alert-danger">Email not found or you already have unsubscribed from our mailinglist!</div>';
        }
    }
} 

$id=$\u GET['id'];
$email=$_获取['email'];
//解码id和电子邮件字符串
$id_decode=base64_decode(urldecode($id));
$email_decode=base64_decode(urldecode($email));
if((isset($\u服务器['HTTP\u REFERER'])和&!empty($\u服务器['HTTP\u REFERER'])){
如果(strtolower(parse_url($_SERVER['HTTP_REFERER'],PHP_url\u HOST))!=strtolower($_SERVER['HTTP_HOST'])){
/*如果不是从您自己的服务器,则将执行以下所有代码*/
$filename='subscribers/'。$id_decode..txt';
//删除订阅服务器条目
如果(文件_存在($filename)){
取消链接($filename);
echo“”。$email_decode.'已成功从我们的邮件列表中删除!';
}
否则{
echo“未找到电子邮件,或者您已取消订阅我们的邮件列表!”;
}
}
} 

取消订阅链接是否实际打开?您可以通过在取消订阅脚本中添加一些日志记录来跟踪是否发生了这种情况:

file_put_contents('unsublog.txt', date('Y-m-d h:i:s') . ',' . $id . ',' . $email . ',' . $_SERVER['REMOTE_ADDR'] . "\n", FILE_APPEND | LOCK_EX);
可能发生的情况是,接收服务器可能会在消息实际读取之前打开消息中的所有链接——这在gmail等大型提供商中变得非常普遍。这样做是为了检查链接目标是否存在恶意软件,但当然,在您的情况下,这也会导致立即取消订阅

解决此问题的方法是不立即处理退订请求,而是首先确认退订页面请求,即需要第二个请求才能实际退订

另一种方法(可与手动方法同时使用)是支持
列表取消订阅
消息头,以及相关的
列表取消订阅帖子
头,以实现一键单击功能。它们分别在和中定义。如果你搜索这些术语,你会发现很多教程和其他资源来帮助你设置它

file_put_contents('unsublog.txt', date('Y-m-d h:i:s') . ',' . $id . ',' . $email . ',' . $_SERVER['REMOTE_ADDR'] . "\n", FILE_APPEND | LOCK_EX);