Nginx通过secure_link模块实现带签名、有时效的私密下载:服务端用密钥对路径+过期时间拼接后MD5生成签名,Nginx在location中用secure_link提取参数、secure_link_md5校验签名与时间戳,验证失败返回403、过期返回410,成功则通过alias映射文件路径;需确保前后端拼接逻辑、密钥、时间同步严格一致。

在 Nginx 中通过 secure_link 模块可以生成带签名、有时效性的下载链接,有效防止资源被非法盗链或篡改。核心在于服务端用密钥对路径和过期时间做哈希签名,Nginx 在请求时验证签名与时间戳是否合法。
启用并配置 secure_link 指令
Nginx 默认已编译该模块(无需额外安装),只需在 location 块中启用:
- 使用
secure_link $arg_md5,$arg_expires;提取 URL 中的签名(md5)和过期时间(expires)两个参数 - 用
secure_link_md5指令定义服务端签名规则:拼接原始路径 + 过期时间 + 密钥,再做 MD5(注意顺序和格式) - 若验证失败,
$secure_link变量为 空;若过期,值为0;成功则为1
生成安全下载链接的逻辑
链接形如:https://example.com/download/file.zip?md5=abc123&expires=1735689600,其中:
-
expires是 Unix 时间戳(秒级),代表链接失效时刻 -
md5是对"/download/file.zip" + "1735689600" + "your_secret_key"做 MD5 得到的 32 位小写字符串 - 注意:路径必须与 Nginx 配置中 location 匹配的 URI 完全一致(含前导斜杠)
Nginx 完整配置示例
以下是一个可直接使用的下载 location 配置:
location /download/ {
# 提取 URL 中的 md5 和 expires 参数
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$uri$arg_expires$remote_addr your_secret_key";
<pre class="brush:php;toolbar:false;"># 验证失败或过期时返回错误
if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410; # Gone:链接已过期
}
# 验证通过,映射到真实文件路径
alias /var/www/files/;}
说明:$remote_addr 可加入客户端 IP 实现“一 IP 一签”,增强安全性;密钥建议存于独立文件并通过 include 引入,避免硬编码。
后端生成签名的 Python 示例
实际业务中,通常由应用后端动态生成带签名的链接:
import hashlib
import time
<p>def gen_secure_url(path, expires, secret="your_secret_key"):</p><h1>注意:path 必须以 '/' 开头,且与 Nginx location 中匹配的 URI 一致</h1><pre class="brush:php;toolbar:false;">signature = hashlib.md5(f"{path}{expires}{secret}".encode()).hexdigest()
return f"https://example.com{path}?md5={signature}&expires={expires}"生成 5 分钟后过期的链接
url = gen_secure_url("/download/report.pdf", int(time.time()) + 300) print(url)
关键点:确保后端拼接字符串的格式、字符编码、密钥内容与 Nginx 配置完全一致,否则验证必失败。
不复杂但容易忽略:时间同步很重要——Nginx 服务器与生成链接的服务端系统时间偏差超过过期窗口,就会导致误判过期;建议统一使用 NTP 同步。











