Nginx 用 secure_link 模块实现鉴权防盗链,通过 $arg_st 和 $arg_e 提取签名与过期时间,以 secure_link_md5 拼接密钥、$uri 和时间戳生成校验签名,依据 $secure_link 值返回 403、410 或正常响应。

要实现带鉴权和过期时间的资源防盗链,核心是用 Nginx 的 secure_link 模块做签名校验,不依赖后端、不查数据库,纯由 Nginx 在请求时完成验证。关键不在“封谁”,而在“只放行合法签名且未过期”的请求。
配置 secure_link 的基本结构
必须在 location 块中启用,不能写在 if 或其他条件块内。典型结构包含三部分:
-
提取参数:用
secure_link $arg_st,$arg_e;从 URL 中读取签名(st)和过期时间(e),两者缺一不可 -
定义签名规则:用
secure_link_md5 "your_secret$uri$arg_e";告诉 Nginx 怎么算“正确签名”——拼接密钥、请求路径(不含查询参数)、时间戳,再 MD5 -
根据 $secure_link 变量值做响应:
• 空字符串 → 缺参数或格式错,返回 403
•"0"→ 签名对但已过期,建议返回 410(Gone)
•"1"→ 签名和时效都通过,正常提供文件
一个可直接用的 location 示例
保护 /download/ 下所有文件,密钥为 abc123:
location /download/ {
secure_link $arg_st,$arg_e;
secure_link_md5 "abc123$uri$arg_e";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
if ($secure_link = "1") {
alias /data/assets/;
}
}
注意:alias 路径末尾不加斜杠,且需确保该目录下有对应文件;若用 root,则路径拼接逻辑不同,容易出错,推荐用 alias。
生成合法链接的关键细节
前端或脚本生成的 URL 必须与 Nginx 校验逻辑完全一致,否则必失败:
- 过期时间
e必须是 Unix 时间戳(秒级),例如1717027200表示 2026-05-29 00:00:00 UTC - 签名
st是对字符串"abc123/download/file.zip?e=1717027200"(注意:含?e=xxx)做 MD5,再 Base64 URL 安全编码(去掉=,替换+为-,/为_) - 最终链接形如:
https://example.com/download/file.zip?st=KvXqLzR8YmJkNzE2MzQ1& e=1717027200
增强安全性的小技巧
单纯用 URI + 密钥 + 时间戳,签名可被转发复用。如需绑定用户或限制传播,可在拼接字符串中加入额外字段:
- 加客户端 IP:
secure_link_md5 "$remote_addr:abc123$uri$arg_e";(同一 IP 才能使用) - 加用户唯一标识(需后端注入):
secure_link_md5 "uid_123:abc123$uri$arg_e";(要求生成链接时已知 uid) - 避免泄露真实文件路径:用
rewrite隐藏原始路径,但注意$uri值以 rewrite 后为准,签名逻辑需同步调整

















