使用 Nginx 的 X-Sendfile 机制控制文件访问权限(php版)

BBS或者网站经常会有只有你有权限才能看到这个页面,或者下载这个资源,日前探访了nginx服务器怎么实现这个文件控制的,用到了x-sendfile。

一、什么是 X-Sendfile?

X-Sendfile 是一种将文件下载请求由后端应用转交给前端 web 服务器处理的机制,它可以消除后端程序既要读文件又要处理发送的压力,从而显著提高服务器效率,特别是处理大文件下载的情形下。

X-Sendfile 通过一个特定的 HTTP header 来实现:在 X-Sendfile 头中指定一个文件的地址来通告前端 web 服务器。当 web 服务器检测到后端发送的这个 header 后,它将忽略后端的其他输出,而使用自身的组件(包括 缓存头 和 断点重连 等优化)机制将文件发送给用户。

不过,在使用 X-Sendfile 之前,我们必须明白这并不是一个标准特性,在默认情况下它是被大多数 web 服务器禁用的。而不同的 web 服务器的实现也不一样,包括规定了不同的 X-Sendfile 头格式。如果配置失当,用户可能下载到 0 字节的文件。

使用 X-Sendfile 将允许下载非 web 目录中的文件(例如/root/),即使文件在 .htaccess 保护下禁止访问,也会被下载。

不同的 web 服务器实现了不同的 HTTP 头
SENDFILE 头 使用的 WEB 服务器
X-Sendfile Apache, Lighttpd v1.5, Cherokee
X-LIGHTTPD-send-file Lighttpd v1.4
X-Accel-Redirect Nginx, Cherokee

使用 X-SendFile 的缺点是你失去了对文件传输机制的控制。例如如果你希望在完成文件下载后执行某些操作,比如只允许用户下载文件一次,这个 X-Sendfile 是没法做到的,因为后台的 php 脚本并不知道下载是否成功。

二、NGINX怎样使用?

        Nginx 默认支持该特性,不需要加载额外的模块。只是实现有些不同,需要发送的 HTTP 头为 X-Accel-Redirect。另外,需要在配置文件中做以下设定

    location /game/ {
         internal;
         alias /data/app/php/open.game.liebao.cn/default/game/;    //文件可以放到别的目录
         error_page 404 =200 @backend;                                         // 如果访问出现404转发到后台服务器
     }   
    location @backend {
       #proxy_pass http://test.open.game.cn;                       // 可以客户端发起请求时,将这个目录的请求代理到其他机器 
        rewrite ^/game/(.*)$ /read_file.php?fn=$1 last;                 // 客户端发起请求时,rewritet跳转到后台程序
    }   

     internal 表示这个路径只能在 Nginx 内部访问,不能用浏览器直接访问防止未授权的下载。

三、php程序怎样使用?

 <?php
$pay = 2;                                   
$path = $_GET["fn"];   //获取用户访问的url参数
if ($pay>1)                   //付过钱的 加上X-Accel-Redirect的头,就能访问到,否则无法访问
{
        // header("Content-Type: application/octet-stream");            //文件下载时候用到
         header("X-Accel-Redirect: /game/".$path);
}
?>
如果加上了加上X-Accel-Redirect的头,这样用户就会下载到 /game 这个路径下的文件。我们的文件权限控制就实现了。

阅读更多

没有更多推荐了,返回首页