2011-08-04 38 views
0

我正在銷售訂閱查看服務。一旦用戶付款,他們就可以通過電子郵件向他們發送唯一的URL。該鏈接設置爲在某段時間後過期,但我想只允許前三個IP地址在鏈接到期之前使用該鏈接來停止盜版。我這樣做是爲了避免另一個運行數千個登錄的數據庫。我假設我可以寫入一個目錄,並有一個文件名作爲鏈接的後綴(在這種情況下爲zFZpj4b2AkEFz%2B3O),最多可以在文件中列出三個IP。高級PHP:只允許前三個IP點擊一個唯一的URL

這一切運作良好,到目前爲止禁止該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,如果它存在,拒絕訪問什麼?

+0

你需要一些人的驗證,像搜索引擎工具欄和病毒程序會自動跟隨鏈接,並可能不必要地算作一個印象。 – Dunhamzzz

+0

謝謝,但它是一個唯一的電子郵件只有一個到期。 –

回答

2

爲此,您必須爲每個訂閱創建一個表。

table subscription: subId, subCode, subVisitTimes, subVisitedIP

subCode將會像zFZpj4b2AkEFz%2B3O

每次訪問,你使用$_SERVER['REMOTE_ADDR']客戶端的IP。

  1. 如果確實存在subVisitedIP則允許訪問。
  2. 如果它不存在,則檢查subVisitTimes值:

    • 如果subVisitTimes = 3則拒絕訪問
    • 如果subVisitTimes < 3則允許訪問,並通過一個增加它的價值還添加客戶端的IP,以subVisitedIP(你應該使用連載函數來存儲三個IP的數組)。
1

你將要爲此設置一個簡單的數據庫。您只需要一行 - 散列/標識,原始IP,過期等,並且只需在訪問耗盡時將過期設置爲1即可。這樣,您不會運行代價昂貴的DELETE查詢,並且如果需要的話,您可以簡單地每月幾次刪除這些行,以節省空間。

否則,它會變得太複雜,更容易出錯使用平面文件。

+0

謝謝你的答案。我想我可能不得不放棄我所做的。我非常希望避免數據庫。您是否知道任何付費的PHP腳本會限制生成的鏈接上的點擊次數?再次感謝。 –

+0

一個想法:當第一次按下鏈接並拒絕訪問(如果存在)時,忘記3個IP如何存儲服務器端Cookie? –

+0

然而,我不願意爲你寫一首。如果你確實沒有使用數據庫,那麼處理平面文件/ etc可能會有點麻煩,但是可以完成。 –

相關問題