admin管理员组文章数量:1531657
2023年12月14日发(作者:)
在web应用中,常常会有文件需要下载。如果这些文件是非常私密的,直接用web服务器下载,就不能检查文件的下载权限。以往遇到这种需要权限的情况,都是用程序语言判定权限后,使用程序语言来读取文件并输出,这样就能解决权限问题。但是使用程序语言来读取文件又带来了效率上的问题,如果文件体积比较大或者下载并发数比较大,服务器很快就不堪重负。
基于这种情况,web服务器软件提供了相应的解决办法:使用一个response header来控制下载。目前squid、apache、lighttpd、nginx等http server都有支持这种方式,但是他们的response header的名字都不一样:
1 nginx: X-Accel-Redirect
2 squid: X-Accelerator-Vary
3 apache: X-Sendfile
4 lighttpd: X-Sendfile/X-LIGHTTPD-send-file
消除行号
用response header控制下载的原理都大同小异:
当客户端发起请求下载某个文件时,因为并没有X-Accel-Redirect头,web服务器并不会立刻就把文件输出给客户端;而是将这个请求交给后端的程序语言,程序语言验证认为该客户端可以下载这个文件,就写出相应的X-Accel- Redirect头并结束处理;X-Accel-Redirect头返回时经过前端的web服务器,web服务器检查到这个头之后,才把文件输出到客户端。
那么,如果客户端伪造一个X-Accel-Redirect头来读取呢?当然也是不能下载的,因为web服务器只认识后端发来的X-Accel- Redirect头,客户端发来的不算。
于是下面就用nginx来实现上述的这个流程:
1、改变目录权限,客户端发起请求时,将这个目录的请求都交给后端
1 location /down/ {
2 alias /data/html/download/;
3 internal;
4 error_page 403 =200 @backend;
5 }
6
7 location @backend {
8 proxy_pass ;
9 }
这样,用户访问如 /down/(等)这样的地址时,将不能下载文件,nginx会把请求交给后端服务器。
2、在后端服务器配置一个rewrite
1 rewrite "^/down/(.*)$" /read_?id=$1 last;
消除行号
这个rewrite的目的是把请求 /down/指向到一个php程序语言上,由程序语言处理。
3 、写一个php程序判断权限
1 /**
2 * 自己的业务逻辑
3 * 验证通过后向nginx发送X-Accel-Redirect允许下载
4 */
5 //todo: oxxo
6
7 header("Content-Type: application/octet-stream");
8 header("X-Accel-Redirect: /mp3/".$id.".mp3");
输出X-Accel-Redirect头之后,文件才能被下载,否则客户端什么都得不到。
版权声明:本文标题:Accel-Redirect response header控制文件下载 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1702558601a13321.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论