基于 Nginx + Java(SpringBoot) 实现带权限验证的静态文件服务器,支持文件下载、PDF预览和图片预览。
需要注意的是,无需权限判断的图片不建议使用此方法,大量的图片访问会增加后台服务器的处理压力。
实现原理
本质上是使用了X-Sendfile功能来实现,X-Sendfile 是一种将文件下载请求重定向到Web 服务器处理的机制,该Web服务器只需负责处理请求(例如权限验证),而无需执行读取文件并发送给用户的任务。
X-Sendfile可显著提高后台服务器的性能,消除了后端程序既要读文件又要处理发送的压力,尤其是处理大文件下载的情形下!
Nginx也具有此功能,但实现方式略有不同。
在Nginx中,此功能称为X-Accel-Redirect。
用户请求文件,权限控制时序图
实现步骤
1、静态文件通过file_server访问,会被设置为internal,即只能内部访问不允许外部直接访问。
# 文件下载服务 location ^~ /file_server { # 内部请求(即一次请求的Nginx内部请求),禁止外部访问,重要。 internal; # 文件路径 alias /home/file/; limit_rate 200k; # 浏览器访问返回200,然后转由后台处理 error_page 404 =200 @backend; }
2、所有静态资源请求均被重定向到Java后台,经过权限验证后才能访问。
# 文件下载鉴权 location @backend { # 去掉访问路径中的 /file_server/,然后定义新的请求地址。 rewrite ^/file_server/(.*)$ /uecom/attach/$1 break; # 这里的url后面不可以再拼接地址 # 定义后台鉴权服务 proxy_pass http://192.168.1.101:9999; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
JAVA SpringBoot 后台权限验证
用户请求只需要传递附件参数和身份token,不再需要传递服务器的真实路径。
例如:
http://127.0.0.1:9222/file_server/img_file?id=123456&token=**********
权限校验完成,返回设置文件请求路径
response.setHeader("X-Accel-Redirect", "/file_server" + attach.getAttachPath());
重点是X-Accel-Redirect配置返回服务器文件的真实路径,该路径返回后由Nginx内部请求处理,不会暴露给请求用户。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。