开发者

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

开发者 https://www.devze.com 2023-03-26 06:33 出处:网络
I am selling a subscription viewing service. Once people have paid they get a unique URL e-mailed to them. The link is set to expire after a certain time but I\'d like to only allow the first three IP

I am selling a subscription viewing service. Once people have paid they get a unique URL e-mailed to them. The link is set to expire after a certain time but I'd like to only allow the first three IP addresses to use the link before it expires to stop piracy. I'm doing it like this to avoid having yet another database running holding thousands of logins. I assume I can write to a directory and have a filename as the suffix of the link (zFZpj4b2AkEFz%2B3O in this case) with up to three IPs listed in the file.

It all works well so far barring the IP address counting and the unique link the e-mail looks like this:

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

The file download.php looks like this:

<?
$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开发者_StackOverflow社区 = ($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;
}
?>

Can any kind soul take pity on someone who has spent far too long looking at this already please ? :) Thanks very much.

--EDIT --

A thought: Forgetting the 3 IPs what about storing a Server-side cookie when the link is pressed the first time and denying access if it exists ?


To do this, you have to create a table for each subscription.

table subscription: subId, subCode, subVisitTimes, subVisitedIP

subCode will be something like zFZpj4b2AkEFz%2B3O

for each visit, you get client's IP using $_SERVER['REMOTE_ADDR'].

  1. If it does exist in subVisitedIP then allow access.
  2. If it does not exist then check subVisitTimes value:

    • if subVisitTimes = 3 then deny access
    • If subVisitTimes < 3 then allow access and increase its value by one also add client's IP to subVisitedIP (you should use serialize function to store array of three IPs).


You're going to want to set up a simple database for this. You only need one row - the hash/id, the original IP, expired, etc and can simply set expired to 1 when access runs out. This way you're not running costly DELETE queries, and if need be you can simply delete those rows all at once a couple times a month to save space.

Otherwise it's going to get too complex and more error-prone using flatfiles.

0

精彩评论

暂无评论...
验证码 换一张
取 消