2012-10-04 34 views
4

我希望允許客戶通過PayPal向我購買一些內容。我會提供多種無形商品。當某人完成其中一件商品的購買時,它們將被重定向到一個着陸頁 - 我們稱之爲「thank_you.php」 - 它會自動排隊下載,並允許鏈接排隊下載,以防它沒有自動啓動。這將通過將唯一的項目ID傳遞到下載頁面(「download.php」)來完成。PHP:讓用戶只能下載購買的文件

這種方法實質上是一種模仿從這些線程頂部答案:

PHP generate file for download then redirect

A PHP script to let users download a file from my website without revealing the actual file link in my website?

然而,我擔心,一旦用戶的「thank_you.php」他們可以免費下載他們的物品,然後用Firebug(或者等同)編輯物品ID並下載另一個物品:

<a href="download.php/38a205ec300a3874c867b9db25f47c61">Download Here</a> 

<a href="download.php/7c8ddc86c0e4c14517b9439c599f9957">Download Here</a> 

我需要你們的想法和幫助誰是遠遠比我更清楚這個:什麼(&如何)我可以實現作爲一個解決方案,將仍然允許同一客戶訪問和休閒,但防止這個操縱?

編輯:該ID哈希值是用來預覽和整個網站引用該項目,我不害怕的人猜測,而是他們在瀏覽網站在一個單獨的標籤來獲取其他ID,只是不斷下載不同的項目。

+0

...他們怎麼樣才知道7c8ddc86c0e4c14517b9439c599f9957? – ceejayoz

+3

是不是很明顯的ceejay?那是我想到的第一個散列 – AlienWebguy

+0

你的散列對應什麼?例如他們對特定的文件,或者他們建立了用戶,文件等?無論如何,聽起來好像你害怕有人猜測隨機散列是有效的。 。 。除非你想要定時清理哈希並使它們過期,這聽起來像是你必須處理的事情? – ernie

回答

3

當他們進行付款時,將可用的下載ID和隨機散列存儲在付款表中。使用散列來獲得ID。散列應該永遠不會與特定產品相關,而是與付款相關。

+0

你是絕對正確的 - 這是我錯過的安全層。這應該讓人們仍然可以購買它 - 沒有註冊,我想唯一的利用就是人們在哈希的使用壽命期間共享鏈接(這沒什麼大不了的,我不相信人們會叫嚷要免費下載我)。非常感謝您的快速回復。 –

1

你可以實現的最簡單的事情之一是一個記錄系統來跟蹤用戶的購買。您可以將請求的ID與存儲的與用戶購買相關的ID進行交叉引用。如果它們不相關,請不要提供該文件。

+0

非常感謝您的回覆,不幸的是,我知道很多人會真的討厭「註冊」越來越多的網站;因此,我真的希望將這些提供給有效的PayPal賬戶的「客人」。 –

+0

那麼,爲什麼不讓ID讀一次,然後刪除?就像說,他們想要music.mp3。你用random4356string或其他的散列來存儲與music.mp3的數據庫關係,然後當下載發生一次時,從數據庫中刪除該關係或將其設置爲使用狀態。如果用戶需要恢復它,也許他們需要聯繫您並提供原始散列表 –

1

您需要跟蹤用戶在數據庫中購買了哪些項目。然後download.php可以檢查用戶是否購買了他們正在下載的物品。

+0

這是否會拒絕「客人」購買和下載? –

3

我原來的答覆:

您將需要存儲(在數據庫或會話變量)的用戶可以訪問哪些項目,每個你會生成一個唯一的隨機令牌。該令牌將用於識別購買的物品。將令牌傳遞給他們可以下載的頁面(在會話變量,POST參數中,或作爲url中的最後一個選項,即GET)。在需要下載的頁面中,您將使用會話信息查詢數據庫/會話變量,以識別客戶和傳遞的令牌(但是您是否通過它),並檢索要下載的文件。

如果您需要保留重新下載的購買物品清單,您也可以這樣做,但請記住在用戶請求下載時再次創建令牌。如果您喜歡,也可以添加到期日期。


現在我已經通過引用答案我想你將需要怎麼做更詳細的性質提到了幾個備選方案,然後再。

可能厄尼是正確的,我不應該假設你有一個會議。可能是我應該告訴你如何做一個會話。

所以我會選擇其中一個選項來執行,最簡單的選項。


<?php 
    //Oh, I'm in a PHP page... 
    //check if there is not a session 
    if (session_id() != '') 
    { 
     //Ok, there is no session, let's create one 
     session_start(); 
    } 
    //Now we are sure there is a session 
    //Let's store in the session the id of the file I want to allow to download 
    $_SESSION['download'] = GetFileId(); 
    //GetFileId will do some mambo jambo expecto patronum to return an id 
    //The id will be 38a205ec300a3874c867b9db25f47c61 or something 
?> 
在下載頁面

現在....

<?php 
    //Oh, I'm in another PHP page... 
    //check if there is not a session 
    if (session_id() != '') 
    { 
     //no session? screw you, no download for you 
     header('Location: sorry.php'); 
    } 
    else 
    { 
     //Now we are sure there is a session 
     //Let's get from the session the id of the file I want to allow to download 
     $id = $_SESSION['download']; 
     //Now get the url to redirect to allow the download 
     $url = GetUrl($id); 
     //GetUrl will do some mambo jambo expecto patronum to return an url 
     //Ok, now we are going to return that file... 
     //So put the correct MIME type 
     header('content-type: image/gif'); //if it is a gif... 
     //Load the file 
     $contents = file_get_contents($url); 
     echo $contents; 
     //That's the only output 
     exit(); 
    } 
?> 

請注意,我這樣做只允許訪問從PHP文件,這樣我就可以先驗證用戶是否有權訪問。你不應該讓用戶只是把網址(即使他不能猜到)和訪問文件。因此,如果您正在運行服務器,則希望將這些文件放在服務器Web文件夾之外,或者如果您使用託管服務,則使用.htaccess(或託管提供的其他機制)保護它們。


Comenting這個解決方案:

它操作簡單,易於實現。然而它有一些缺點:

  • 如果會話在下載之前終止,用戶失去了他的錢*。
  • 有沒有明確的方式實施重新下載。
  • 它仍然容易受到會話劫持的影響(我知道,但是最好是安全的)。

*:假設連接丟失,並且會話在客戶端中過期。哦,不,我們不需要任何滿意的顧客。

所以,你真的,真的,需要一個數據庫來支持這一行動,並創建隨機令牌,preferibly與到期日期。

+0

其實你的第一個答案几乎是我需要的解決方案 - 在reciepts表中,生成一個新的隨機字符串作爲僅用於該購買的id,而不是使用該項目的id。我只是選擇了本格里芬的回答,因爲他先回答了,但你都是對的。 –

4

雖然這些其他的答案假設你有一個會話,使用用戶名,聽起來就好像你剛剛創建的哈希到一個文件以隱藏文件名。換句話說,你最好在鍵盤上放一個猴子錘子,並把它作爲你每個文件的文件名。

然後它聽起來像您擔心用戶會通過,英鎊在鍵盤上,並以某種方式與完全匹配您的猴子做了什麼而告終。這不太可能。

更可能的是有人會複製並粘貼您的鏈接並共享它。聽起來好像您需要至少爲驗證方案添加一個圖層(例如,散列用戶名和項目ID),或者一旦使用鏈接就會過期。

從您的評論,它也聽起來好像你正在使用的哈希值,以確定您的網站上的另一部分,這意味着用戶可以通過對另一部分查看源確定項目的哈希值的項目你的網頁。在這一點上,通過默默無聞的安全感就像我用代碼詞(例如「魚意味着約翰,貓意味着麗莎」),當與某人閒聊並說「魚和貓正在發泄」時,所有的同時都有一張一邊寫着任何人都可以看到的映射文件。這聽起來像你只是想隱藏文件名,所以人們無法猜測它們。這就是所謂的security through obscurity,並不真的給你買太多。

大多數其他答案都假設一個項目存在,並且它會有多個不同的哈希指向它(例如file1,它將有hash1,hash2和hash3都是有效的鏈接)。在這種情況下,他們創建了多個散列,每個散列對於某個用戶+項目都是唯一的。我認爲他們也假定網站上的每個人都會將下載項目引用爲item1而不是hash1,這聽起來像是你在做什麼?

在代碼中的某個地方創建一個字典,該字典中包含項目名稱和散列之間的映射,然後只在下載頁面上用散列替換名稱。再次,這只是安全通過默默無聞,鏈接可以共享,但人們將無法讓哈希只是瀏覽您的網站。

+0

我真的不太擔心猜測哈希值的人。另外,我擔心人們會收集其他物品的散列,並且只需複製粘貼原始物品的次數不定,以便繼續下載不同的物品。我正在尋求幫助,以獲得我失蹤的安全層。 –

+0

@JeremyBuller對,所以使用哈希的目的就是在網站上的其他地方,你把這個項目稱爲'item1'。唯一的地方你應該使用散列將在下載鏈接。 – ernie

+0

啊,我明白了。 Theraot和Ben Griffins早些時候說過,我認爲可能就是這樣。您看到的散列是我使用的實際項目標識符;所以我應該使用隨機散列(以及時間戳+ x的過期日期)來引用該購買僅在我的收件人表中。 –