本方案为:服务端API生成加密字符串,服务端web中间件层实现验证,验证成功则代理访问到真实资源服务器地址 ,适用于流媒体及下载文件服务,图片未验证。
具体实现方案如下:
1,中间件及附加模块
nginx-1.4.6 web中间件
http_accesskey_module web中间件第三方防盗链IP验证模块
http_secure_link_module web中间件自带参数验证模块
2,协助生成加密字符串测试PHP代码
<?php
# 密钥
$secret = 'Tgn.com';
# 获取下载文件地址
$path = $_GET['fn'];
# 给nginx的accesskey模块生成md5码
$accesskey = md5($secret . $_SERVER['REMOTE_ADDR']);
# 下载到期时间,time是当前时间,60表示60秒,也就是说从现在到60秒之内文件不过期
$expire = time() + 60;
# 用文件路径,密钥、过期时间生成加密串
$sec_md5 = str_replace("=", "", strtr(base64_encode(md5($secret . $path . $expire, TRUE)), "+/", "-_"));
# 加密后的下载地址
$output_add_key = "<a href=".$path. "?p=" . $accesskey . "&st=" . $sec_md5 . "&e=" . $expire . ">".$path."</a><br />";
# 未加密的加密的下载地址
$output_org_url = "<a href=".$path.">".$path."</a><br />";
echo $output_add_key;
echo $output_org_url;
4,nginx 配置
location /mp3 { #定义资源文件访问URL主目录
root /home/www;
accesskey on;
accesskey_hashmethod md5;
accesskey_arg "p";
accesskey_signature "Tgn.com$remote_addr";
secure_link $arg_st,$arg_e;
secure_link_md5 "Tgn.com$uri$arg_e";
if ($secure_link = "") { #若secure link字符串获取失败则返回403代码
return 403;
}
if ($secure_link = "0") { #若secure link字符串获取失败则返回403代码
return 403;
}
error_page 404 =200 /match$request_uri; #如果本地没找到则转发请求到fetch目录实现穿越代理
error_log off;
}
location /match/ {
alias /home/html;
proxy_store on;
proxy_set_header Accept-Encoding '';
proxy_set_header Host $host;
proxy_pass http://192.168.170.13:82$request_uri; #请求文件的真实地址
}
5,请求文件完整URL
请求:http://192.168.170.130/htdocs/ngdl.php?fn=/mp3/DR/67940_726560.mp3 通过加密字符串代码生成如下完整URL
完整URL:http://192.168.170.130/mp3/DR/67940_726560.mp3?p=173a2ddde6429e6de2dd7b94d14ed901&st=wkQd3yYD8q2EKv-M550q3g&e=1394658459
方案优缺特点:
1,可定制时间实现URL失效时间
2,URL唯一性,不能复制到其它终端访问
3,该方案中的$remote_addr参数在前端经过多层代理访问时会存在为最后链接访问的代理IP情况,对IP验证效果将减弱