nginx http_secure_link
两种认证方式,
第一种: 临时链接;
第二种: 固定密码链接;
第一种: 临时链接
- 服务端生成md5值和expires过期时间, 代码如下:
$expire = time() + 20;/*链接的有效期*/
$uri = '/audio/979.mp3'; /*访问的资源*/
$remoteAddr = '183.45.175.200';/*访问者的公网IP地址*/
$secret = 'zhuangdebiao'; /*密钥*/
/*拼接字符串, 生成哈希值*/
$hash = base64_encode(md5($expire.' '.$uri .' '.$remoteAddr . ' ' .$secret, true));
$hash = strtr($hash, '+/', '-_'); /*可选*/
$hash = str_replace('=', '', $hash); /*可选*/
/*最终URL*/
echo 'https://yey.zdb.im'.$uri.'?hash='.$hash.'&expires='.$expire;
URL示例 : https://yey.zdb.im/audio/979.mp3?hash=qdmp79trLCCKKVzKAvia4A==&expires=1610085706
- 修改nginx配置
location /audio/ {
secure_link $arg_hash,$arg_expires;
secure_link_md5 "$secure_link_expires $uri $remote_addr zhuangdebiao";
# hash error
if ($secure_link = "") {
return 403;
}
# expire
if ($secure_link = "0") {
return 410;
}
try_files $uri $uri/ = 404;
}
- 从$args即queryString中获取md5值和过期时间
secure_link $arg_hash,$arg_expires;
- 计算md5值的字符串模板
secure_link_md5 "$secure_link_expires $uri $remote_addr zhuangdebiao";
$secure_link_expires 即过期时间 $arg_expires;
$uri 即访问的资源路径;
$remote_addr 即用户的IP地址;
最后一段是密钥 secret;
用空格分隔, 也可以不用空格, 随意字符串都行;
- 如果md5值不相等, 即密钥等参数错误, 返回http 403错误;
- 如果链接过期, 返回410错误;
- 最终, 允许访问资源, 可以proxy_pass或者try_files检测文件是否存在 并返回给客户端浏览器;
第二种: 固定密码链接
uri 格式是 /prefix/hash/link
md5值的 格式是 hex(md5(link.secret))
原链接 https://yey.zdb.im/zdb/979.mp3
固定密码链接, 举例: https://yey.zdb.im/p/1656e96df11cbbcab7186e9f5dd171f3/979.mp3
location /p/ {
secure_link_secret zhuangdebiao; # 密钥
if ($secure_link = "") {
return 403;
}
rewrite ^ /zdb/$secure_link;
}
location /zdb/ {
alias /home/wwwroot/yey/Public/audio/;
internal; # 仅允许内部访问,直接访问会返回404
}
计算md5值的算法:
$prefix = 'p'; /*入口前缀*/
$secret = 'zhuangdebiao'; /*固定的密钥*/
$link = '979.mp3'; /*访问的资源*/
$hash = md5($link .$secret, false); /*十六进制*/
echo 'https://yey.zdb.im'.'/'.$prefix.'/'.$hash.'/' .$link;