2013-04-11 2 views
1

이것은 PHP 스크립트를 사용하여 서버에서 파일을 다운로드하는 것에 관한 질문입니다. 사용자가 다운로드 링크를 클릭하면 download.php 파일로 처리되고 header을 사용하여 다운로드가 시작됩니다.시간에 하나씩 PHP 스크립트를 사용하여 파일 다운로드

파일을 다운로드 한 후 download.php 파일에 하나의 기능이 있습니다.이 파일은 다운로드 한 파일에 대한 mysql 데이터베이스를 업데이트하고 사용자 계정에서 돈을 공제합니다. 모든 것이 잘 작동합니다.

이제 PC에 다운로드 관리자가 설치되어있는 경우 문제가 발생합니다. 때때로 다운로드는 브라우저와 다운로드 관리자에서 모두 시작되었습니다. 그래서 결국 데이터베이스에 두 가지 다운로드 항목이 있고 사용자 계정에서 돈이 두 번 공제됩니다.

질문 : 한 번에 하나의 다운로드 만 시작할 수 있습니까? 아니면이 일을하는 다른 방법?

다운로드 링크 나는 사용자에게 제공합니다.

<a href='download.php?id=1'>Download Test Video</a> 

파일을 다운로드 할 때 사용하는 스크립트. (download.php) 나는 논리 변경하는 것이 좋습니다

$file = "c:/test.avi"; // $file = $_GET['id']; 
    $title = "Test Video"; 

    header("Pragma: public"); 
    header('Content-disposition: attachment; filename='.$title); 
    header("Content-type: ".mime_content_type($file)); 
    header("Content-Length: " . filesize($file) ."; "); 
    header('Content-Transfer-Encoding: binary'); 
    ob_clean(); 
    flush(); 

    $chunksize = 1 * (1024 * 1024); // how many bytes per chunk 
    if (filesize($file) > $chunksize) { 
     $handle = fopen($file, 'rb'); 
     $buffer = ''; 

     while (!feof($handle)) { 
      $buffer = fread($handle, $chunksize); 
      echo $buffer; 
      ob_flush(); 
      flush(); 
     } 

     fclose($handle); 
    } else { 
     readfile($file); 
    } 

    record_download('user id', 'file id'); 
+1

이 편리하게 얻을 수 있습니다 ... http://stackoverflow.com/questions/14233850/how-to-prevent-file-hotlink-from-internet-download-manager-idm .. 아이디어는이다 이러한 다운로드 관리자 차단 ... 다른 아이디어가 있습니다. 그러나 이것은 그들 중 하나입니다 ... –

+0

비디오 다운로드마다 요금을 청구합니까? 유료보기를 사용하고 웹 페이지에 삽입하는 것이 좋습니다. 전체 비디오에 대해 요금을 청구하는 경우 고객이 비디오를 구매 한 다음 원하는만큼 여러 번 다운로드하십시오 (또는 제한을 설정하십시오) –

+4

사용자를 위해이 설정을 사용하는 방법에 대한 확신이 너무 많지 않습니다. 그러나 나는 최근에 비슷한 것을 완성했다. 그들이이 파일을 다운로드하면 고유 한 URL이 표시됩니다 (다운로드/). 그들이 이것을 다시 처리하려고 시도하면 이전 토큰이 사용됩니다. 물론 이것은 활성 세션이있는 경우에만 작동합니다. – Dave

답변

1

관심있는 사람은 여기로 의견을 이동하십시오.

내가 지불해야만했던 기능은 지불이 처리 된 후 고유 한 다운로드 링크였습니다. 이것들은 취해진 조치들입니다.

  • 지불을 처리하고 다운로드 가능한 파일의 IP 주소, 파일 및 경로를 캡처하십시오.이 정보는 데이터베이스에 저장하십시오.
  • 결제가 성공적으로 완료되면 고유 토큰을 생성하는 함수 (예 : sha1(microtime().$transactionid))를 실행하여 데이터베이스에 저장합니다 (참고 : 프로덕션 환경에서는 microtime()을 사용하지 말고 임의 문자열 생성기 사용).
  • .htaccess을 사용하여 다운로드 링크를 생성했습니다 (예 : http://domain.com/download/<token>).htaccess로 내용 :

    RewriteRule ^download/([a-z0-9-]) /download.php?token=$1 
    
  • 옵션 : 자신의 IP는 우리가 데이터베이스에있는 것과 일치하는 경우, 계속 진행하여 사용자가 파일을 다운로드 할 수 있습니다. 그렇지 않은 경우 사용자에게 로그인하여 IP 주소를 업데이트하고 다운로드를 시작할 수 있도록 요청합니다.
  • 토큰이 있으면 데이터베이스에 열을 추가하여 여러 번 다운로드하지 못하도록하는 것과 같은 유효성 검사를 거의 수행 할 수 있습니다. download_downloaded INT(1) DEFAULT 0 여기서 1로 설정하면 다운로드됩니다 . 나는 그들의 파일이 과정에서 타락 된 경우에 대비하여, 다운로드 후 그들을 잠그기 전에 하루를 사용자에게 제공 할 것을 제안한다.
  • 다운로드 카운터 등 기타 추가 항목
  • 마지막으로 위의 코드를 사용하여 다운로드를 시작하십시오. 나는 그것이 조금 다르게 구조화했을 것이다. 그들은 로그인 한 후

download.php (이 여러 번 일어로) 사용자가 자신의 다운로드 링크를 잃은 경우

$token = $_GET['token']; 
$allow_download = FALSE; // Can never be too careful.. 

... 
//Database lookup to get the file ID 
... 

$file = "c:/test.avi"; // now from the database call 
$title = "Test Video"; 

// Do any additional validation here 
// returns TRUE or FALSE (Boolean) -- Custom function to query the database 
$allow_download = check_if_downloadable('user_id', 'file_id', 'token_id'); 
record_download('user id', 'file id'); 

// After validation is complete, allow them to download 
if ($allow_download === TRUE){ 
    header("Pragma: public"); 
... 

, 우리는 자신의 회원 홈 페이지에서 자신의 다운로드 링크를 표시 그리고 다시 다운로드를 시작할 수 있습니다 (허용하는 경우).

이 정보가 도움이되기를 바랍니다. 지금은 코드 예제를 제공하지 못해 죄송합니다.

대부분이 데이터베이스를 쿼리하는 것입니다.

0

: 첫째

보안 허점이 있습니다!

두 사람이 해당 링크로 파일을 다운로드하기 시작하면 두 사람이 해당 파일에 대한 지불을 무시할 수 있습니다. 누군가 파일을 다운로드하여 다른 사람에게 보내면 어떻게 될까요? 그래서, 그다지 문제는 아닙니다. 안 그래?

하지만 정말로 안전하다고 생각되면 CSRF 토큰을 첨부하는 옵션이 있습니다.

1

언젠가 저희 웹 사이트에서 다운로드 링크가 필요합니다. 이 링크를 클릭하면 모든 유형의 파일, 이미지, PDF가 다운로드됩니다. 간단한 PHP 스크립트를 사용하여이 작업을 수행 할 수 있습니다.

그림 이름 "shafiq_photo.jpg"를 다운로드하려는 경우 매개 변수는 파일 이름 "shafiq_photo.jpg"입니다. 위의 파일에서 사용하는 "download.php"라는 PHP 파일 이름을 만듭니다.

<?php 
$file = $_GET["file"]; 

if (file_exists($file)) { 
header('Content-Description: File Transfer'); 
header('Content-Type: application/octet-stream'); 
header("Content-Type: application/force-download"); 
header('Content-Disposition: attachment; filename=' . urlencode(basename($file))); 
// header('Content-Transfer-Encoding: binary'); 
header('Expires: 0'); 
header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
header('Pragma: public'); 
header('Content-Length: ' . filesize($file)); 
ob_clean(); 
flush(); 
readfile($file); 
exit; 
    } 
?> 
관련 문제