生成ip和时间限制下载链接

Mor*_*eza 6 php download

有一个直接的链接下载文件.用户可以在付款后下载该链接,如下所示:

http://example.com/download/webapp.rar
Run Code Online (Sandbox Code Playgroud)

但我需要生成ip和时间有限的下载链接,以防止leech与他人的文件.我想这样做而不使用任何数据库.这样的事情:

http://example.com/download.php?a5fds588fgdf
Run Code Online (Sandbox Code Playgroud)

要么

http://example.com/download/a5fds588fgdf
Run Code Online (Sandbox Code Playgroud)

有什么提示吗?

Hik*_*ndo 27

有一个非常好的nginx模块这样做.

URL有两个参数 - 让我们称之为s(安全性)和t(时间戳).安全性是从时间戳,路径和盐生成的安全哈希(在您的情况下只是添加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
Run Code Online (Sandbox Code Playgroud)

核实:

$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');
}
Run Code Online (Sandbox Code Playgroud)

现在你只需要将下载重写为这个"中间人" - 脚本,你就完成了.

nginx的重写示例:

location /download {
    rewrite ^.*$ /download.php last;
    break;
}
Run Code Online (Sandbox Code Playgroud)

我并不熟悉apache重写,所以你可以自己检查一下.

如果您使用以下模块之一,则不需要自己验证所有这些,并且在性能方面要好得多,但请注意,它提供了更多配置,有时还有另一种方法来生成url和hash(请参阅此处的模块文档).

或者您只需使用nginx安全链接模块:http://wiki.nginx.org/HttpSecureLinkModule

还有一个轻巧的吊坠:http: //redmine.lighttpd.net/wiki/1/Docs :ModSecDownload

或者是nginx安全下载模块:http://wiki.nginx.org/HttpSecureDownload

也许还有apache的东西......也许你可以用那里的重写来做点什么......

  • 我发现我需要添加`$ path = parse_url($ _SERVER ['REQUEST_URI'],PHP_URL_PATH);`所以接收器脚本中的散列路径没有拉入查询变量,而`$ timestamp <= time() `应该是`$ timestamp> = time()` (5认同)

Tom*_*Tom 5

如果您不担心人们能够解码某些参数(例如 IP 或时间戳),您可以尝试以下操作:

<?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);
?>
Run Code Online (Sandbox Code Playgroud)

现在这是为 ip $key->ip 获取唯一密钥,有效期为 1 小时。

要验证它:

<?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 ?');
}
?>
Run Code Online (Sandbox Code Playgroud)

大功告成 :) 不涉及数据库。之后只是散列和匹配散列。

但我想一个简单的方法$_SESSION[$file_id] = time()+3600;可以在一行中解决问题......虽然不那么有趣。