【问题标题】:How to combine rewrites with different roots in location blocks如何将重写与位置块中的不同根结合起来
【发布时间】:2014-03-05 03:39:41
【问题描述】:

当进行重写的位置块需要不同的根时,我很难理解如何控制对 PHP 脚本的重写。

这是简化的示例。我的包罗万象的前端控制器必须在 web 根目录下,但 firewall.php 脚本不能在。

这样做的目的是提供对不在根目录下的下载文件的门控访问。

server {

    # Requests for media forced through firewall script outside web root
    # /path/to/secure-area/firewall.php
    #
    location ^~ /downloads/ {
       root /path/to/secure-area;
       rewrite ^/.+$ /firewall.php last;
    }

    # Regular requests bootstrap front controller under web-root
    # /path/to/web-root/index.php;
    #
    location / {
        root /path/to/web-root;
        index index.php
        if ( -e $request_filename ) {
            break;
        }
        rewrite ^.+$ /index.php last;
    }

    # Execute PHP via php-fpm
    # rewrites hitting this are not mapping request_filename properly
    #
    location ~ \.php$ {
       if ( !-f $request_filename ) {
         return 404;
       }
       include /usr/local/nginx/conf/fastcgi_params;
       fastcgi_pass   unix:/tmp/php.sock;
       fastcgi_index  index.php;
    }
}

显而易见的解决方案是拥有一个共同的根,但在我的情况下这是不可能的。我无法将安全位置放置在 Web 根目录下,并且 Web 根目录必须保持原样。

看起来root 指令仅在定义它的位置块内有效。重写单独工作正常,但是当~ \.php 块被击中时,根丢失了。

我显然做错了,那我应该如何实现呢?

【问题讨论】:

    标签: nginx rewrite php


    【解决方案1】:

    未经测试,但这样的东西应该可以帮助你。它使用http://wiki.nginx.org/XSendfile 从不同的根目录提供受保护的内容。还使用 try_files,这是一个更好的前端控制器模式。

        server {
    
        # More here: http://wiki.nginx.org/XSendfile
        #
        # To serve /downloads/some.zip
        # get php to set the http header:
        #
        # X-Accel-Redirect: /downloads/some.zip
        #
        # and then the file /path/to/secure-area/downloads/some.zip
        # will be sent by nginx
        location /downloads/ {
          internal;
          root   /path/to/secure-area;
        }        
    
        location / {
            root /path/to/web-root;
            index index.php
            try_files $uri $uri/ /index.php;
        }
    
        # make sure you read http://wiki.nginx.org/Pitfalls
        location ~* \.php$ {
          try_files $uri =404;
          fastcgi_pass   unix:/tmp/php.sock;
          fastcgi_index  index.php;
          include /usr/local/nginx/conf/fastcgi_params;
        }
    }
    

    【讨论】:

    • 感谢 try_files 提示。我会看看那个。我希望我可以使用 X-Send,但我不能有两个原因。 (1) 该站点也必须部署到 Apache,并且并不总是具有等效模块。 (2) 发送X-headers 的PHP 脚本也不能在web 根目录下。 (代码库重叠)
    • 啊,您可以轻松地修复 nginx 方面的问题,以便从 webroot 外部发送 X-Accel-Redirect。多年来没有接触过 Apache 配置:P
    • 从根外部发送标头本质上是我要问的问题。我已经使用alias 对其进行了排序,但这意味着复制 fastcgi 的东西。
    • 在您的示例中, php-fm 部分处理常规内容,而位于不同根文件夹中的 firewall.php 处理身份验证?本质上它们是两个不同的 php 应用程序? Apache 配置是什么样的?你也可以在你的问题中发布吗?
    • 我还没有解决 apache 配置问题。如果不再添加,我将接受您的回答,然后我将发布我最终得到的解决方案。巧合的是,刚刚出现了 X-Send 非常适合的事情,所以这对我来说是个好消息。
    猜你喜欢
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 2016-07-05
    • 2020-03-25
    • 2015-10-11
    • 2013-06-10
    相关资源
    最近更新 更多