Dosya indirme kısıtlama

8 Cevap php

Ben şu anda temelde çeşitli dosyaları satış içerecektir bir müşteri için bir web sitesi oluşturma. Bu tabii ki bana bunu yapmak için bir yöntem düşünce değil bir tür aptal hissediyorum yapıyor yapmak için gerçekten ortak bir şey vardır.

Alım yapıldıktan sonra müşteri (onlar da mümkün olacak download linki, hem de onlar için oluşturulacak bir hesabı hakkında bilgi içeren bir download linki ve e-posta içeren e-postaları alma içeren bir sayfaya alınmalıdır ) kendi hesabın kontrol panelinden indirebilirsiniz. Ne olduğunu anlamaya çalışıyorum onu ​​satın alır bir kişi sadece kopyalayıp başka dosyaya direkt linki yapıştırın değil böylece benim sunucuda dosyanın yerini belirsiz / gizleyebilirsiniz nasıl. Ben bir dosya biçimi http://example.com/blah/download/454643, dosyanın gerçek konumuna uygun olmayan bir URL'ye bir bağlantı indirmek için istekte bile, ben hala dosyayı bulmak mümkün olabileceğini düşünüyorum sunucu? Gerçekten izinleri soruyorum neden olan, benim sunucuda nasıl çalıştığı hakkında çok fazla anlamıyorum. Şimdiden teşekkürler :)

8 Cevap

Siz temelde dosyaya kullanıcılara doğrudan URL'sini vermeyin. Sunucu tabanlı izinleri Burada yapılacak bir şey yok.

Say you have the required file(s) saved in /data/files/file.pdf (good practice to store files out of your web root). You can provide the users a link to download which looks something like /download.php?auth=32

When a user clicks the link, download.php will check if the session/cookie is authenticated and if the download id is valid (in case you have time based download expiry) Then download.php will read the required file from its location and send it to the browser with appropriate headers to force download.

Web kök yan dosyaları depolamak, ama sonra bunları saklamak klasör php.ini dosyasında "open_basedir" direktifi olduğundan emin olun, bu bir PHP script onları erişim sağlayacak. Web kök dışında saklayarak asla direkt HTTP üzerinden erişilebilir olmaz demektir.

Bir PHP komut dosyası, akarsu bu cevaplar listelenen olanlar gibi / bir dosyayı okudum. Onun büyük bir dosya ekstra zaman için hesaba "max_execution_time" değiştirmeniz gerekebilir komut dosyasını okumak için alacaktır. Bu komut kullanıcının kimliğini ve dosya için ödemiş kontrol sağlayacaktır.

Bir değişkene o klasörde talep dosyasını yeniden yazar komut ile klasöründe bir. Htacces koydu. Bu o değil iken onlar dosyayı doğrudan erişen sanki görünmesini sağlar. Şahsen ben sadece sadece basit şeyleri tutmak için bu klasöre tek bir komut dosyası koymak istiyorum. Yani:

http://www.yourdomain.com/files/expensive_song.mp3

aslında yeniden yazar:

http://www.yourdomain.com/files/download_file.php?filename=expensive_song.mp3

İyi şanslar.

Eğer lighttpd.conf çalışan erişiminiz varsa, kesinlikle Mod_SecDownload modülü kontrol etmelisiniz. Ben güvenli video ve resim dosyaları satılan bir önceki proje üzerinde bu kullandım.

As the webserver doesn't know anything about the permissions used in the app, the resulting URL would be available to every user who knows the URL.

mod_secdownload removes this problem by introducing a way to authenticate a URL for a specified time. The application has to generate a token and a timestamp which are checked by the webserver before it allows the file to be downloaded by the webserver.

The generated URL has to have the format:

<uri-prefix>/<token>//<rel-path> which looks like "yourserver.com/bf32df9cdb54894b22e09d0ed87326fc/435cc8cc/secure.tar.gz"

bir MD5

  1. gizli bir dize (kullanıcı tarafından sağlanır)
  2. (/ Ile başlar)

As you can see, the token is not bound to the user at all. The only limiting factor is the timestamp which is used to invalidate the URL after a given timeout (secdownload.timeout).

Sen URL alıcı için bir yetkilendirme kodu olması olabilir. Onu tekrar giriş yapmak için olsun, kod boru, sonra için ona dosyasıdır olduğuna bakın. İşte osCommerce PHP kodu bir exemple (Ben yazdığım bir uzun zaman önce).

// Now send the file with header() magic
  header("Expires: Mon, 26 Nov 1962 00:00:00 GMT");
  header("Last-Modified: " . gmdate("D,d M Y H:i:s") . " GMT");
  header("Cache-Control: no-cache, must-revalidate");
  header("Pragma: no-cache");
  header("Content-Type: Application/octet-stream");
  header("Content-disposition: attachment; filename=" . $downloads['orders_products_filename']);

  if (DOWNLOAD_BY_REDIRECT == 'true') {
// This will work only on Unix/Linux hosts
    tep_unlink_temp_dir(DIR_FS_DOWNLOAD_PUBLIC);
    $tempdir = tep_random_name();
    umask(0000);
    mkdir(DIR_FS_DOWNLOAD_PUBLIC . $tempdir, 0777);
    symlink(DIR_FS_DOWNLOAD . $downloads['orders_products_filename'], DIR_FS_DOWNLOAD_PUBLIC . $tempdir . '/' . $downloads['orders_products_filename']);
    if (file_exists(DIR_FS_DOWNLOAD_PUBLIC . $tempdir . '/' . $downloads['orders_products_filename'])) {
      tep_redirect(tep_href_link(DIR_WS_DOWNLOAD_PUBLIC . $tempdir . '/' . $downloads['orders_products_filename']));
    }
  }

Burada oldukça benzer bir şey için yaptıklarını örnek kod:

// $mimeType is the mime type of the file
header('Content-type: ' . $mimeType);
// this will get the size of the file
// (helps for giving the size to the browser so a percent complete can be shown)
header('Content-length: ' . (string) (filesize($path)));
// disposition is either attachment (for binary files that can't be read by the browser) 
// or inline (for files that can be read by the browser
// some times you have play with this to get working so users get the download window in all browsers
// original filename is the name you want to users to see 
// (shouldn't have any special characters as you can end up with weird issues)
header('Content-Disposition: ' . $disposition . '; filename=' . $originalFilename);
// the next 2 lines try to help the browser understand that the file can't be cached
// and should be downloaded (not viewed)
header('Pragma: Public');
header('Cache-control: private');
// this will output the file to browser
readfile($path);

Bunu tabii ki çok kez indirilmiş değildir sağlamak için bu herhangi bir kontrol giriş ve günlük ekleyebilirsiniz.

Insanların yolunu anlamaya olamaz Ayrıca, daha önce de söylediğim gibi, dışarıda (veya üzeri) dosya koymak web sunucusu belge kök sağlamak. Yoksa öyle olsa bile sadece iç insanlar daha kolay dosya listesini erişebilir dizinde bir şifre koymak olabilir, ancak bu tavsiye etmem. (Eğer doc kök dışında bir şey koymak eğer sadece bunu.)

Böyle Lighty ve Nginx gibi bazı web sunucuları, X-SendFile başlığını uygulamak. Diyelim ki sizin görünümü dışarı gemi istediğiniz dosyaya işaret eden bir X-SendFile başlığı dönmek olabilir, bir Django uygulaması var diyelim. lighttpd'nin sonra yerine bu dosyayı hizmet edecektir.

Dosyası (bu bir 301 yönlendirme değil) olmayan bir web erişilebilir bir konumda olabilir ve uygulama başlığını hizmet vermektedir, çünkü ilk yetkilendirme yapabilirsiniz.

Bu uygulamadan statik dosyalara hizmet daha iyidir. Webserver statik dosyalar için optimize edilmiş ve hızlı olacak, ve kaynaklar üzerinde çok hafif. Eğer X-SendFile kullanarak düşünmelisiniz birkaç istekleri daha fazla taşıma ediyorsanız.

Burada bu konuda oldukça iyi bir blog yazısı var:

http://blog.zacharyvoase.com/2009/09/08/sendfile/

Lighttpd / PHP talimatları burada bulabilirsiniz:

http://redmine.lighttpd.net/wiki/1/X-LIGHTTPD-send-file

Nginx talimatları burada bulabilirsiniz:

http://wiki.nginx.org/XSendfile

Da aynı şeyi yapar erken tahliye Apache mod var gibi görünüyor:

https://tn123.org/mod_xsendfile/

Ben satın dayandığını gördüm indir URL'ler bir sürü biri id tahmin o kadar basit yapmak değil url parçası olarak bazı guid ve diğer dinamik bilgileri kullanma eğiliminde. Sen yolunun bir parçası olarak guid / datetimepurchased / id veya böyle bir şey ile bitebileceğini.

Ek bir seçenek kullanıcı yükleme ek bir güvenlik katmanı verilen hangi ilerlemesine izin verilmeden önce kaydedilir sağlamak olacaktır.

Peki, ilk, kesinlikle dosyasına doğrudan bağlantı istemiyorum. Muhtemelen belirli kriterler yerine getirildiği takdirde, bir dosya indirmek sonuçları oluşturulan kimliği argümanı ile (hatta sadece bir sayfa) yarattık bir hizmete kullanıcıya bir bağlantı göndermek isteyeceksiniz.

Bu kriterler zor, gerçekten, kullanıcı birden fazla dosya indirmek için izin gerekir gibi (bu durumda o tam dosyayı ilk defa indirmek için başarısız, ya da yanlışlıkla, vb siler), ancak bir bağlantı çalışmaları kez, Eğer onu öldürmek kadar çalışır.

Ben indirme isteklerini filtrelemek için zaman ya da IP kullanarak ya öneririm.

Zaman: Birisi sizden dosya satın aldığında, onlar sadece günde 1 veya bazı tür için dosyayı indirmek mümkün olacak onları bilgilendirmek. Evet, diğer kişi o gün içinde dosyayı indirmek, ama sadece 1 gün için olabilir. Siz de bu konuda bir indirme sınırı koyabilirsiniz, bu yüzden sadece o 5 kez (bu normal) indirebilirsiniz.

IP: Birisi sizden dosya satın alırken, sadece bu IP dosya indirmek mümkün olacak onları bilgilendirmek. Bu dosyayı karşıdan yüklemeye çalıştığınızda indirme hizmeti kesinlikle bu kontrol edebilirsiniz.

Hem de, aynı zamanda kolay kullanılabilir görünüyor.

Durumda (veya ikisini), (bazı insanlar) statik olanları alamadım zaman içinde dosyayı indirmek, ya da zaman sınırı (ya da başka bir bilgisayar / IP den sonra tekrar almak istemedim müşterilerine işlemek için hazır olun .) Onlar tekrar ödemek istemiyor, ve muhtemelen zorunda olmamalıdır.