2

我的网站应用程序中有一个文件夹data,它不在网络根目录中。这样做是为了提高安全性,因此只有某些人才能访问它。通过查看 CakePHP 文档,我使用的代码如下:

foreach($ImageToSort as $FileDisplayKey => $FileDisplayData) {
    $FileName = $ImageToSort[$FileDisplayKey]['Fileinfo']['filename'];
    $WholePathName = 'data/'.$FileName;
}

$this->response->file($WholePathName);
return $this->response;

它加载文件但不在我的视图中(上面的代码在视图中,$ImageToSort是从我的控制器中的 find 调用中设置的)。

那么如何通过某种循环加载不在 webroot 中的文件,以便我可以查看它们并以我选择的方式将它们放置在我的网站上?

PS。我不能将文件放在 webroot 文件夹中,因为有人只需要知道文件的名称就可以获取它。对这些文件的访问需要保留给少数人。

非常感谢您提供的任何帮助,

格伦

更新:

我正在使用 2.4,从我读到的媒体视图不是我应该使用的,但“发送文件”是取代它们的调用。我尝试将它们与以下代码一起使用:

$this->viewClass = 'Media';

$params = array(
    'id'        => $FileName,
    'name'      => 'example',
    'extension' => 'jpg',
    'path'      => APP . 'uploads/test' . DS
);

$this->set($params);

debug($params['id']);
$name = $params['id'];
$path = $params['path'];
$filename = $path.$name;


//echo 'name::' .$name;
echo "<img src=";
echo $filename;
echo ">";

除非我将文件放入 中,否则无法找到该文件/webroot/data/test,然后它可以正常显示。但这完全没有意义吗?我只需要选定的用户来查看选定的文件以解决安全问题。

以下代码在查看/app/data/test路径中的文件时确实有效,

$this->autoRender = false;
$this->response->file(Configure::read('uploads').$WholePathName);

但是这段代码在控制器或视图中使用时没有区别,它仍然只显示文件,没有布局、样式、标题或任何东西。同样,这完全没有意义。

必须有一种方法可以让我可以访问我的文件并读取我需要的文件/文件夹。

格伦

4

1 回答 1

1

创建一个接受路径片段(例如通过查询传递)的适当控制器/动作,检查当前用户是否被允许访问文件,将路径片段与基本路径组合并输出文件内容。

img然后使用视图中元素属性的相应 URL src,即类似

<img src='/files/read/?file=foo/bar.jpg'>

这样,只有授权用户才能访问您的文件。

这是一个非常基本的控制器/动作示例,如果401不允许用户访问文件,它会响应 a,如果404找不到文件、不是文件或不在基本路径中,它会响应万一一切正常,它为文件提供服务:

class FilesController extends AppController
{
    public function read()
    {
        // you'd probably use auth component checks and stuff here
        if(testWhetherUserIsAllowedToAccessFiles() !== true)
        {
            throw new ForbiddenException();
        }

        // make sure that the base path points to a folder that only
        // holds the files that should be accessible!
        $base = ROOT . DS . 'files' . DS;
        $fragment = $this->request->query('file');

        // expand to a canonicalized absolute path, it's way easier to
        // test for validity using the real path
        $path = realpath($base . $fragment);

        // just a basic sanity check, you may want to implement some more
        // security checks to make sure there's really no way to access
        // files outside of the base directory! After all this is just
        // some example code.
        if(
            !!preg_match('~\.\.(\\\\|/)~', $fragment) ||
            $path === false || !is_file($path) ||
            mb_strpos($path, $base) !== 0)
        {
            throw new NotFoundException();
        }

        $this->response->file($base . $fragment);
        return $this->response;
    }
}

从 CakePHP 2.4.8 开始,响应对象会检查可能的路径遍历片段,因此理论上,可能不需要此示例中的额外检查,因为没有通过扩展的真实路径,但原始路径,串联一个!

于 2013-09-26T11:51:54.310 回答