2011-10-27 21 views
5

hay un enlace directo para descargar un archivo. los usuarios pueden descargar después de que el enlace de pago, así:Generar enlace de descarga limitado por tiempo y por IP

http://example.com/download/webapp.rar 

pero necesito generar IP y el tiempo limitado enlace de descarga para evitar la sanguijuela del archivo con los demás. Quiero hacer esto sin usar ninguna base de datos. algo como esto:

http://example.com/download.php?a5fds588fgdf 

o

http://example.com/download/a5fds588fgdf 

es que hay algún consejo?

+10

"Without any databases"? ¿Qué tipo de requisito es eso? Usted * absolutamente * tiene que almacenar algunos datos para resolver este problema, y ​​una base de datos es el * mejor lugar * para hacerlo. ¿Por qué estás tratando de evitar el uso de una base de datos? – meagar

+0

Sin la base de datos, puede lograr esto usando 'cookies' configurando' expiry'. Sin embargo, el problema con eso es que puedes eliminar las cookies. así que esta no es una manera confiable. –

+1

@GhazanfarMir ... aparte del hecho de que las cookies pueden ser falsificadas tan fácilmente que las vuelven prácticamente inútiles para esto ... – DaveRandom

Respuesta

23

Hay un módulo nginx realmente bueno para hacer esto.

La URL tiene dos parámetros: llamémosle s (seguridad) yt (marca de tiempo). La seguridad es un hash seguro generado a partir de la marca de tiempo, la ruta y una sal (en su caso, solo agregue la ip).

$ip = $_SERVER['REMOTE_ADDR']; 
$salt = 'change me cause im not secure'; 
$path = '/download/webapp.rar'; 
$timestamp = time() + 3600; // one hour valid 
$hash = md5($salt . $ip . $timestamp . $path); // order isn't important at all... just do the same when verifying 
$url = "http://mysite.com{$path}?s={$hash}&t={$timestamp}"; // use this as DL url 

Para verificar:

$ip = $_SERVER['REMOTE_ADDR']; 
$salt = 'change me cause im not secure'; 
$path = $_SERVER['REQUEST_URI']; 
$hashGiven = $_GET['s']; 
$timestamp = $_GET['t']; 
$hash = md5($salt . $ip . $timestamp . $path); 
if($hashGiven == $hash && $timestamp <= time()) { 
    // serve file 
} else { 
    die('link expired or invalid'); 
} 

Ahora sólo tiene que volver a escribir las descargas de este "hombre en el medio" -script y ya está.

Ejemplo de reescritura para nginx:

location /download { 
    rewrite ^.*$ /download.php last; 
    break; 
} 

No estoy muy familiarizado con Apache reescribe por lo que puede comprobar esto por sí mismo.

Si está utilizando uno de los siguientes módulos, no necesita verificar todo esto usted mismo y es mucho mejor en cuanto al rendimiento, pero tenga en cuenta que ofrece más configuración y a veces otra forma de generar el url y el hash (ver módulo documentos aquí).

O simplemente utiliza el nginx módulo de enlace seguro: http://wiki.nginx.org/HttpSecureLinkModule

También hay un colgante para el lighty: http://redmine.lighttpd.net/wiki/1/Docs:ModSecDownload

O el nginx segura módulo de descarga: http://wiki.nginx.org/HttpSecureDownload

Tal vez hay algo para Apache también ... Tal vez puedas hacer algo con reescrituras allí ...

+0

¡Esa es una manera increíble y brillante de expresarlo! Gracias ! – Tom

+0

@ Hikaru-Shindo Gracias amigo, ¿puedes poner mi enlace de muestra en tu secuencia de comandos (para mi prueba) – Nulled

+0

@NuLLeR He reescrito mi respuesta para que coincida con tu ejemplo y haya agregado más información sobre lo que se debe tener en cuenta. –

4

Si no está preocupado por la gente que es capaz de decodificar algunos parámetros como la IP o marca de tiempo que podría intentar algo como esto:

<?php 
$salt = 'SALTING'; // Hash cipher 
$key = new stdClass(); 
$key->limit = time()+3600; // 1 hour limit 
$key->ip = $_SERVER['REMOTE_ADDR']; 
$key->security = sha1(sha1($salt.serialize($key))); // Double sha1 for fun 

$key_param = base64_encode(serialize($key)); 

echo sprintf('http://mysite.com/download/%s', $key_param); 
?> 

Ahora que es para obtener una clave única, válida 1 hora, para IP $ clave-> ip.

para verificarlo:

<?php 
$salt = 'SALTING'; 
$key = $_GET['key']; 
$key = base64_decode($key); 
$key = unserialize($key); 
if($key->security != sha1(sha1($salt.serialize($key)) || $_SERVER['REMOTE_ADDR'] != $key->ip) { 
    throw new Exception('Security breach. U mad bro ?'); 
} 
?> 

y ya está :) Ninguna base de datos en cuestión. Solo hash y hashes coincidentes después.

Pero supongo que un simple $_SESSION[$file_id] = time()+3600; haría el truco en una línea ... No es tan divertido.

+2

@meagar ¿Problema? – Tom

+0

Than k tu por hacerme jajarte en el trabajo. – meagar

+0

@Tom Gracias, ¿dónde debo configurar mi nombre de archivo "webapp.rar"? – Nulled

0

Mi consejo más importante sería utilizar una base de datos.

Pero si es absolutamente positiva tiene que hacerlo sin continuación, se recomienda usar una biblioteca de almacenamiento en caché como caché-lite: http://pear.php.net/manual/en/package.caching.cache-lite.intro.php

Muchos marcos de PHP (si está utilizando uno) también vienen con una biblioteca de almacenamiento en caché

Puede almacenar en caché la IP y la clave aleatoria que asigne junto con una fecha de caducidad (algunas bibliotecas de caché también le permitirán asignar el tiempo de validez de caché)

Cuestiones relacionadas