基于 JSON 正文的 nginx 过滤



我有一个Java API服务器,位于nginx服务器后面。nginx服务器提供HTTPS,速率限制,日志记录,分析等。

有一个特定的 HTTP 端点/my-file-upload/{:file-id}它占用 JSON 主体类型:

{
FileName: <string>,
Content: <base 64 encoded string>,
}

这需要由这种服务器组合来处理。

Java 服务器处理实际的文件内容处理。但是,我希望有一个允许从nginx服务器传递到Java服务器的各种文件扩展名(不一定是正文中的文件魔术(的白名单。

例如,我希望通过过滤请求正文 JSON 的FileName字段,仅允许 PDF (.pdf( 和.txt文件请求。到目前为止,我已经使用了基于location的nginx过滤来过滤url。但是,在这里我想根据请求正文进行过滤,是否有使用配置文件在nginx中实现此目的的标准方法,或者我需要编写任何插件或是否有任何标准插件来实现这一点?

您有几个选择,具体取决于您想要的"正确"程度。

真正粗略和肮脏的方式是在客户端添加一些代码来获取文件扩展名,然后使用XMLHttpRequest.setRequestHeader()修改XMLHttpRequest代码,以将其添加到具有文件类型的请求中的其他标头字段。例如X-Filetype: pdf

然后在您的 Nginx 上传位置中,您拒绝此标头中具有错误值的任何上传:

if ($http_x_filetype !~ (pdf|txt)) {
return 415;
}

Nginx现在返回其他上传的415 Unsupported Media Type

优点: 很容易 缺点: 四处走动很容易,在一个位置内使用if条件是 Nginx 亵渎

在规模的另一端,您在 javascript 中实现 FileReader API,将事件侦听器附加到文件上传表单,然后在客户端选择文件时使用 FileReader 将前几个字节切成数组缓冲区,并将其添加到标头中,如前面的示例所示。

在 Nginx中,您需要auth_request模块,该模块不是默认构建的标准 Nginx 安装,但几个包管理器发行版都有它。您可以通过运行以下命令进行检查:

nginx -V 2>&1 | grep -qF -- --with-http_auth_request_module && echo ":)" || echo ":("

在您的上传位置块中,您可以为 Nginx 设置一个内部位置,以便在每个请求上调用。来自此子请求的响应代码确定 Nginx 是否允许客户端访问。

location /my-file-upload {
auth_request /filecheck;
........
}
location /filecheck {
internal;
proxy_pass http://127.0.0.1/my-auth-script.php; #or whatever
proxy_set_header X-Filehex $http_x_filehex;
....
}

将所需的任何信息传递给内部脚本,该脚本执行文件类型验证和客户端标识。预期文件的 MD5 哈希,预期文件大小,任何可能有助于确保是否允许上传,那么您获得的文件就是您希望获得的文件。

如果您的脚本满意,则返回 200,如果不是,则返回 403。然后,如果Nginx收到200响应,则代理您的上传服务器,如果收到403响应,则拒绝请求

最新更新