如果您唯一关心的是限制对某些 URL 的访问,您可以查看 this post on Securing URLs 和 Secure Link Module in Nginx。
它提供了相当简单的方法来保护您的文件——加密您的 URL 的最基本和最简单的方法是使用 secure_link_secret 指令:
server {
listen 80;
server_name example.com;
location /cats {
secure_link_secret yoursecretkey;
if ($secure_link = "") { return 403; }
rewrite ^ /secure/$secure_link;
}
location /secure {
internal;
root /path/to/secret/files;
}
}
访问cat1.zip 文件的URL 将是http://example.com/cats/80e2dfecb5f54513ad4e2e6217d36fd4/cat1.zip,其中80e2dfecb5f54513ad4e2e6217d36fd4 是在连接两个元素的文本字符串上计算的MD5 哈希:
- 哈希之后的 URL 部分,在我们的例子中是
cat1.zip
-
secure_link_secret 指令的参数,在本例中为 yoursecretkey
以上示例还假设通过加密 URL 访问的文件存储在 /path/to/secret/files/secure 目录中。
此外,还有一种更灵活但也更复杂的方法,通过使用secure_link 和secure_link_md5 指令来使用ngx_http_secure_link_module 模块保护URL,通过IP 地址限制URL 访问,定义过期时间网址等
如果您需要完全隐藏您的网址(包括 cat1.zip 部分),您需要在以下各项之间做出决定:
- 在 Nginx 端处理加密 URL 的解密 - 编写自己的,或重用别人编写的模块
- 在应用程序中的某处处理加密 URL 的解密 — 基本上使用 Nginx 将加密 URL 代理到应用程序,在该应用程序中解密它们并采取相应措施,如 @cnst 上面所写。
这两种方法各有利弊,但 IMO 后一种方法更简单、更灵活——一旦你设置了代理,你就不需要太担心 Nginx,也不需要用一些特殊的先决条件来编译它;无需使用您已经在应用程序中编写的语言编写或编译代码(除非您的应用程序包含 C、Lua 或 Perl 代码)。
这是一个简单的 Nginx/Express 应用程序示例,您可以在其中处理应用程序中的解密。 Nginx 配置可能如下所示:
server {
listen 80;
server_name example.com;
location /cats {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:8000;
}
location /path/to/secured/files {
internal;
}
}
在应用程序 (Node.js/Express) 方面,您可能会遇到以下情况:
const express = require ('express');
const app = express();
app.get('/cats/:encrypted', function(req, res) {
const encrypted = req.params.encrypted;
//
// Your decryption logic here
//
const decryptedFileName = decryptionFunction(encrypted);
if (decryptedFileName) {
res.set('X-Accel-Redirect', `/path/to/secured/files/${decryptedFileName}`);
} else {
// return error
}
});
app.listen(8000);
以上示例假定受保护文件位于/path/to/secured/files 目录。它还假设如果 URL 可访问(正确加密),则您正在发送文件以供下载,但如果您需要执行其他操作,则同样的逻辑将适用。