Proteger descargas
En muchas ocasiones no queremos que la gente pueda acceder a nuestros archivos directamente, no sin pasar primero por nuestra página. En este tutorial os presentaré una manera de hacerlo.
Lo que haremos será crear una “redirección” al archivo en PHP, asà el usuario no podrá en ningún caso saber realmente donde está el archivo o como se llama.
<?php
if (!isset($_GET['i']) || empty($_GET['i'])) {
exit();
}
$root = "descargas/";
$file = basename($_GET['i']);
$path = $root.$file;
$type = '';
if (is_file($path)) {
$size = filesize($path);
if (function_exists('mime_content_type')) {
$type = mime_content_type($path);
} else if (function_exists('finfo_file')) {
$info = finfo_open(FILEINFO_MIME);
$type = finfo_file($info, $path);
finfo_close($info);
}
if ($type == '') {
$type = "application/force-download";
}
// Definir headers
header("Content-Type: $type");
header("Content-Disposition: attachment; filename=$file");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $size);
// Descargar archivo
readfile($path);
} else {
die("El archivo no existe.");
}
?>
Con esto conseguimos que al pasarle por GET un nombre de archivo, lo busque en el directorio “descargas”, quedando nuestro enlace como algo asà “www.midominio.es/?archivo.rar” (teniendo en cuenta que el archivo de php se llame index.php)
Pero nosotros no nos quedaremos aquÃ, iremos un paso mas allá. Ahora mismo estamos pasando por GET el nombre del archivo, pero,¿ y si en lugar del nombre, le pasamos una ID y guardamos en una base de datos el nombre del archivo vinculado a esa ID?
PodrÃamos guardar en una tabla algo como esto:
z97xht - archivo1.rar z9467 - archivo2.rar zsd3ht - archivo3.rar 456b6 - archivo.3rar
Y realizar consultas a la base de datos para poder encontrar el archivo, de manera que nuestro enlace serÃa asÃ: “www.midominio.es/?z97xht”
Entonces modificarÃamos un poco el código del script para que quedara de la siguiente manera:
<?php
if (!isset($_GET['i']) || empty($_GET['i'])) {
exit();
}
$conn = mysql_connect("dbhost", "dbuser", "dbpass") or die('Could not connect: ' . mysql_error());
$dbselect = mysql_select_db("dbname") or die ('Could not select database');
$idfile = $_GET['i'];
$nombrearchivo = mysql_query("SELECT `nombre_archivo` FROM `descargas` WHERE `id`='$idfile'");
$row = mysql_fetch_row($nombrearchivo);
$root = "descargas/";
$file = basename($row[0]);
$path = $root.$file;
$type = '';
if (is_file($path)) {
$size = filesize($path);
if (function_exists('mime_content_type')) {
$type = mime_content_type($path);
} else if (function_exists('finfo_file')) {
$info = finfo_open(FILEINFO_MIME);
$type = finfo_file($info, $path);
finfo_close($info);
}
if ($type == '') {
$type = "application/force-download";
}
// Definir headers
header("Content-Type: $type");
header("Content-Disposition: attachment; filename=$file");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $size);
// Descargar archivo
readfile($path);
} else {
die("El archivo no existe.");
}
?>
Lo ideal es que crees un subdominio (por ejemplo d.kazike.es) a través del cual gestionar las descargas y que en ese subdominio tengáis este script llamándolo index.php (asà nos podemos ahorrar escribir el nombre del archivo y usarlo como d.kazike.es/?ID)
Ya como ultima vuelta de tuerca, vamos a poner una comprobación de dominio, para asegurarnos que no enlazan a nuestros archivos desde fuera. El PHP serÃa asà y deberÃa ir al principio del script:
if (strpos($_SERVER['HTTP_REFERER'],"kazike.es") == false){
header("Location: http://www.kazike.es");
}
Asà si nos enlazan desde fuera, al no venir desde nuestra página, los enviaremos a nuestra página principal.
en noviembre 9th en 15:11
Uau! Felicidades por el blog, te está quedando muy bien y profesional!
en noviembre 9th en 18:51
Muchas gracias!
Voy poniendo cosas que me comentan que pueden estar interesantes.