【问题标题】:Serving protected files with Symfony2 and Nginx X-accel-redirect使用 Symfony2 和 Nginx X-accel-redirect 提供受保护的文件
【发布时间】:2015-04-29 16:59:10
【问题描述】:

我的配置是带有 nginx 的 php-fpm 5.4。我需要提供一些受保护的文件。因此,我与 Symfony 核对用户是否具有正确的权限,然后我希望 nginx 使用 X-accel-redirect 标头提供文件(swf)。

symfony 中的控制器:

/**
 * @Route("/protected/swf")
 */
public function sendFileAction()
{
    // [...]    

    // user rights are ok, serve the file

    $fileName = 'myfile.swf';
    $filePath = $this->get('kernel')->getRootDir() . '/../files/' . $fileName;

    $response = new BinaryFileResponse($filePath);
    $response->trustXSendfileTypeHeader();
    return $response;
}

还有我的 nginx 配置:(http://wiki.nginx.org/XSendfile)。这些文件位于 web 目录(文件)之外的目录中。

location /files/ {
     internal;
     root   /path/to/folder;
}

它可以工作(我的意思是文件已提供),但我认为它没有使用 XSendfile。如果我理解正确,nginx 将提供一个文件,如果标题

X-Accel-Redirect: /files/myfile.swf;

存在。但是 BinaryFileResponse 使用磁盘上的路径来查找我的文件,并且不知道应该像上面那样设置这个头。

有人可以给我举个例子吗? 谢谢!

【问题讨论】:

    标签: symfony nginx x-accel-redirect


    【解决方案1】:

    所以,我阅读了 BinaryFileResponse 代码源,试图弄清楚如何继续。我想我已经理解了,但有人可以确认这是正确的吗?至少,它似乎按预期工作。

    我要提供的文件位于文档根目录之外的一个名为 private-dir 的目录中。

    想法是修改请求,让 nginx 知道映射:

    我的新控制器:

    /**
     * @Route("/protected/swf")
     */
    public function sendFileAction()
    {
        // [...]    
        // user rights are ok, serve the file
    
        $fileName = 'myfile.swf';
        $filePath = $this->get('kernel')->getRootDir() . '/../private-dir/' . $fileName;
    
        $this->getRequest()->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
        $this->getRequest()->headers->set('X-Accel-Mapping', '/private_dir/=/path/to/private-dir');
    
        BinaryFileResponse::trustXSendfileTypeHeader();
        $response = new BinaryFileResponse($filePath);
        return $response;
    }
    

    稍后 BinaryFileResponse 将解析这些标头以将文件的真实路径替换为私有 URI,因为它出现在 nginx 网站 conf 中:

    location /private_dir {
        alias /path/to/private-dir;
        internal;
    }
    

    【讨论】:

    • 这在我尝试时不起作用。我得到一个 500 /private_dir/file doest not exist.. 我不明白为什么你必须在 $request 上设置这些标题而不是响应.. 这很奇怪吧?但是BinaryFileResponse的来源确实长得像。我遇到了类似的问题,我确实得到了正确的响应,但是状态码为 404...stackoverflow.com/questions/39841131/…
    【解决方案2】:

    我也这样做(检查用户权限,然后从文档根目录外提供文件),但我之前没有使用 BinaryFileResponse 完成此操作,所以这个答案可能不是您想要的。

    我的做法是使用IgorwFileServeBundle

    这样你就可以使用类似的配置了..

    igorw_file_serve:
        factory: sendfile
        base_dir: $kernel.root_dir%/../files
    

    然后像服务器一样提供文件。

    return $this->get('igorw_file_serve.response_factory')->create(
        $filePath,      // Relative to the base_dir
        $fileMimeType,
        array(
            'serve_filename'    => $fileName,
            'inline'            => false,
        )
    );
    

    【讨论】:

    • 感谢您的回答。但是您是否也更改了 nginx 配置中的某些内容?
    • 老实说,我现在在 Apache 上使用它,但我没有什么特别的设置。
    猜你喜欢
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 2012-09-01
    • 2018-02-02
    • 1970-01-01
    • 2012-10-09
    • 2019-03-26
    相关资源
    最近更新 更多