使用 Symfony @Route 覆盖文件请求

Override file request with Symfony @Route

我是 Symfony 的新手,我正在做一个测试项目来提高我的知识。事实上,我正在学习 Routing,我想做的是在请求扩展名为 .disabled 的文件时拒绝访问。我说的是放在 web 目录中的文件。因此,例如,位于 web/config.php.disabled 的文件不能是 executed/downloaded.

然后我创建了这样一条路线

/**
 * @Route("{req}disabled", name="denyAccess", requirements={"req"=".+"})
 */
public function denyAccessAction(Request $request, $req)
{
    return new Response('Access denied');
}

并且在我请求不存在的文件时工作正常(例如 http://my.website/file.php.disabled)。但是当我请求现有文件时,路由不起作用,我可以毫无问题地下载该文件。所以我想请求一个放在 web 目录中的现有文件将覆盖任何路由。

如何让我的路由比 web 目录中请求的文件具有更高的优先级?

web/ 是一个资源文件夹,Symfony 无法通过路由系统控制这个文件夹(除非 URI 不存在)。

如果您试图拒绝访问 config.php,它已经在他体内完成了:

if (!isset($_SERVER['HTTP_HOST'])) {
    exit('This script cannot be run from the CLI. Run it from a browser.');
}

if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
    '127.0.0.1',
    '::1',
))) {
    header('HTTP/1.0 403 Forbidden');
    exit('This script is only accessible from localhost.');
}

因此,您只能从本地主机(开发环境)访问,但从外部主机访问,这将拒绝访问。


另一方面,您可以使用 Web 服务器配置拒绝访问其他文件:

这是一个 Web 服务器配置问题。在基本的 Symfony Web 配置中,为了提供包含在您的 web/ 目录中的文件,您的 Web 服务器不会调用 PHP 或 Symfony。如果找不到给定 URL.

的文件,您的 Symfony 应用程序只是后备

现在的问题是:您使用什么作为 Web 代理? Nginx、Apache、HAProxy ?

如果你使用的是 Nginx,你的配置中应该有这样的东西:

location / {
    try_files $uri /app_dev.php$is_args$args;
}

location ~ ^/app_dev\.php(/|$) {
    fastcgi_pass unix:/var/run/php/phpX.X-fpm.sock;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    fastcgi_param DOCUMENT_ROOT $realpath_root;
}

在第一个块中,try_files 完全按照我告诉你的方式进行:首先它将尝试 return 与给定 $url 关联的文件,然后如果找不到, 它回落到 app_dev.php 具有相同的路由参数。然后它被第二个块捕获,将请求转发到 PHP.

因此,对于您的特定用例,我建议您添加一个块以拒绝请求带有“.disabled”的文件的用户。在 Nginx 中,这很容易完成:

location ~ \.disabled/?$ {
    return 403;
}

对于其他 Web 服务器技术,只需查看文档即可了解如何执行此操作。