高级PHP:只允许一个唯一的URL被前三个ip点击


Advanced PHP: Allow a unique URL to be clicked by the first three IPs only

我正在销售订阅观看服务。一旦人们付费,他们就会得到一个独特的URL。该链接被设置为在一定时间后过期,但我想只允许前三个IP地址使用该链接之前,它到期,以阻止盗版。我这样做是为了避免运行另一个数据库来保存数千个登录。我假设我可以写入目录,并将文件名作为链接的后缀(在本例中为zFZpj4b2AkEFz%2B3O),文件中列出最多三个ip。

到目前为止,除了IP地址计数和唯一链接之外,一切都运行良好,电子邮件看起来像这样:

http://www.blah.com/download.php?file=zFZpj4b2AkEFz%2B3O

download.php文件如下所示:

<?
$time = time();
include('settings.php');
class RC4Crypt {
        /**
         * Encrypt the data.
         * @param string private key.
         * @param string data to be encrypted.
         * @return string encrypted string.
         */
        function encrypt ($pwd, $data)
        {
                $key[] = '';
                $box[] = '';
                $pwd_length = strlen($pwd);
                $data_length = strlen($data);
                for ($i = 0; $i < 256; $i++)
                {
                        $key[$i] = ord($pwd[$i % $pwd_length]);
                        $box[$i] = $i;
                }
                for ($j = $i = 0; $i < 256; $i++)
                {
                        $j = ($j + $box[$i] + $key[$i]) % 256;
                        $tmp = $box[$i];
                        $box[$i] = $box[$j];
                        $box[$j] = $tmp;
                }
                $cipher = '';
                for ($a = $j = $i = 0; $i < $data_length; $i++)
                {
                        $a = ($a + 1) % 256;
                        $j = ($j + $box[$a]) % 256;
                        $tmp = $box[$a];
                        $box[$a] = $box[$j];
                        $box[$j] = $tmp;
                        $k = $box[(($box[$a] + $box[$j]) % 256)];
                        $cipher .= chr(ord($data[$i]) ^ $k);
                }
                return ($cipher);
        }
        /**
         * Decrypt the data.
         * @param string private key.
         * @param string cipher text (encrypted text).
         * @return string plain text.
         */
        function decrypt ($pwd, $data)
        {               
                return RC4Crypt::encrypt($pwd, ($data));
        }
}
if(!isset($_GET['file']) || empty($_GET['file'])) {
        echo 'Invalid Request';
        return;
}
$data = $_GET['file'];
$id_time = RC4Crypt::decrypt($secret,base64_decode(rawurldecode($data)));
list($product_id,$timestamp) = explode('|',$id_time);
if(!isset($products[$product_id])) {
        echo 'Invalid Request';
        return;
}
if ($timestamp < $time - ($download_life * 60 )) {
        echo 'Link Expired';
        return;
}
if(isset($products[$product_id])) {
print ("<html><head><meta http-equiv=Refresh content='"0;URL=http://www.blah.com/view/'"></head><body></html>");
        return;
}
?>

任何一个善良的灵魂都可以同情那些已经花了太长时间看这个的人吗?:)非常感谢。

——编辑——

一个想法:忘记3个ip,当链接第一次被按下时存储一个服务器端cookie,如果它存在,拒绝访问呢?

为此,必须为每个订阅创建一个表。

table subscription: subId, subCode, subVisitTimes, subVisitedIP

subCode将类似于zFZpj4b2AkEFz%2B3O

对于每次访问,您使用$_SERVER['REMOTE_ADDR']获得客户端的IP。

  1. 如果subVisitedIP中存在,则允许访问。
  2. 如果不存在则检查subVisitTimes值:

      如果subVisitTimes = 3,则拒绝访问
  3. 如果subVisitTimes < 3允许访问并将其值增加1,也将客户端的IP添加到subVisitedIP(您应该使用serialize函数来存储三个IP的数组)。

您将需要为此设置一个简单的数据库。您只需要一行-哈希/id,原始IP,过期等,并且可以在访问耗尽时简单地将过期设置为1。这样你就不用运行昂贵的DELETE查询了,如果需要的话,你可以一个月删除几次这些行来节省空间。

否则使用flatfile会变得太复杂,更容易出错。