基于JSON正文的nginx过滤

时间:2018-07-05 12:12:23

标签: nginx

我在nginx服务器后面有一个Java API服务器。 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中实现此目的的标准方法,还是我需要编写任何插件或是否有任何标准插件来实现此目的?

1 个答案:

答案 0 :(得分:1)

您有几种选择,具体取决于您要执行的方式。

真正的粗暴和肮脏的方式是在客户端添加一些代码以获取文件扩展名,然后使用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,则拒绝该请求