You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby加密URL参数后,PHP端解密逻辑及加载位置咨询

解决方案:在中间处理脚本中解密并完成追踪

你需要在邮件客户端请求加密链接时,先通过一个中间PHP脚本解密出真实的追踪URL参数,然后直接在该脚本内完成数据库更新并返回像素——不需要跳转,这样就能保证邮件打开时的追踪逻辑正常执行,同时对用户完全透明。

具体步骤:

  1. 修改邮件中的加密链接格式
    把原来的加密内容作为参数传给中间处理脚本,比如:

    http://your-domain.com/decrypt_track.php?data=3ISGSfzIiaAU+h2TwF0pNoKDKRenjKfRhehMMN3+OJw=
    

    (注意:如果加密字符串包含+等特殊字符,最好提前用urlencode处理,避免参数解析错误)

  2. 创建decrypt_track.php中间脚本
    这个脚本整合了解密、数据库更新、返回像素的完整逻辑,替代原来分散的文件分工:

    <?php
    require_once("./db_connection.php");
    
    class StringDecrypt {
        function decrypt($string) {
            $encrypted_data = base64_decode($string);
            $key = base64_decode("bzFkaXF3a2Fka2ZqZzAxOGpna2RqYTkxOTQwMjUxMjM=");
            $iv = base64_decode("YWtqZ2tkbGFkamdrYWRzdw==");
            // 兼容原有mcrypt实现(注意:mcrypt已被PHP7.2+弃用,建议看后面的替代方案)
            $result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted_data, MCRYPT_MODE_CBC, $iv);
            // 修正填充移除逻辑,原rtrim不够准确
            $pad = ord($result[strlen($result) - 1]);
            return substr($result, 0, -$pad);
        }
    }
    
    // 1. 获取加密参数
    $encryptedData = isset($_GET['data']) ? $_GET['data'] : '';
    if (empty($encryptedData)) {
        // 即使参数为空,也要返回空像素避免报错
        header('Content-Type: image/gif');
        $img = imagecreatefromgif("px.gif");
        imagegif($img);
        imagedestroy($img);
        exit;
    }
    
    // 2. 解密并解析subid参数
    $decrypter = new StringDecrypt();
    $decryptedUrl = $decrypter->decrypt($encryptedData);
    parse_str(parse_url($decryptedUrl, PHP_URL_QUERY), $params);
    $subid = isset($params['subid']) ? intval($params['subid']) : 0;
    
    // 3. 更新数据库打开统计
    if ($subid > 0) {
        $conn = new mysqli($servername, $username, $password, $db);
        if ($conn->connect_error) {
            // 数据库连接失败也不能中断像素返回
            header('Content-Type: image/gif');
            $img = imagecreatefromgif("px.gif");
            imagegif($img);
            imagedestroy($img);
            $conn->close();
            exit;
        }
        $conn->set_charset("utf8");
        $stmt = $conn->prepare("UPDATE rcpt SET has_opens = has_opens + 1 WHERE id = ? ");
        $stmt->bind_param('i', $subid);
        $stmt->execute();
        $stmt->close();
        $conn->close();
    }
    
    // 4. 返回1x1像素图片,让邮件客户端认为加载成功
    header('Content-Type: image/gif');
    $img = imagecreatefromgif("px.gif");
    imagegif($img);
    imagedestroy($img);
    ?>
    
  3. (推荐)替换弃用的mcrypt为openssl
    PHP7.2及以上版本已移除mcrypt扩展,建议把解密函数改成更稳定的openssl实现:

    function decrypt($string) {
        $encrypted_data = base64_decode($string);
        $key = base64_decode("bzFkaXF3a2Fka2ZqZzAxOGpna2RqYTkxOTQwMjUxMjM=");
        $iv = base64_decode("YWtqZ2tkbGFkamdrYWRzdw==");
        // AES-256-CBC对应Ruby中的aes-256-cbc,块大小为128位
        return openssl_decrypt($encrypted_data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
    }
    

核心逻辑说明

邮件中的像素链接是由客户端直接发起请求的,客户端本身无法执行解密逻辑,所以必须让请求先经过我们的中间脚本:先解密拿到追踪参数,完成数据库统计,最后返回像素图片。这样既保证了链接的安全性,又能正常触发打开统计。

内容的提问来源于stack exchange,提问作者Peter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:52:05