5

我想限制对仅用于管理目的的控制器文件夹的访问。我尝试了多种方法,但没有提出解决方案。这些控制器有密码保护。但是,如果有人碰巧发现了正确的目录,我想将其从视图中删除。这可以做到吗?我宁愿不从 htaccess 做。我可以访问 apache 配置文件,所以我想在那里处理它。

它与 Codeigniter 的路由方式有什么关系吗?或者,我是不是很遥远?

我正在使用的这个不起作用

<Directory /var/www/application/controllers/folder/>
  Order deny,allow
  Deny from all
  Allow from xxx.xxx.xxx.xxx
</Directory> 
4

2 回答 2

3

由于我们重写 url 以使用 CI 的方式,您永远不会匹配您的 Apache 配置,因为您实际上是在请求index.php?{args}. 如果要过滤,则必须在 CI 中进行。您的选择是核心控制器或挂钩。

一种简单的方法是创建一个您的管理/区域脚本扩展的核心控制器,并在那里检查 IP。

像这样的东西:

application/core/MY_Controller.php

class MY_Controller extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->config('permitted_ips');
        // check visitor IP against $config['ips'] array, redirect as needed
    }
}

然后,在您的“敏感”控制器中,扩展 MY_Controller:

application/controllers/admin/seekrit.php

class Seekrit extends MY_Controller
{
    public function __construct() {
        parent::__construct();
        /* at this point any invalid IP has been redirected */
    }
}

现在,如果您已经核心控制器用于其他用途,只需$this->uri->segment()在加载允许的 IP 配置文件并检查/重定向/死亡或您需要做的其他任何事情之前检查它们是否在受限区域。

此外,如果您不需要一个构造函数,则无需在管理控制器中使用构造函数,因为如果未定义父级将被构造。如果您定义一个,请务必致电父母。

您还可以将白名单放入数据库、Redis 等中。

另一种方法是使用钩子,特别是pre_controller钩子。进入该挂钩时,所有安全类和基类都已运行。如果您想以更细化的方式保护部分或全部路由,这将是合适的。在那里,您可以定义一个包含路由的数组,例如:

$protected_routes = array(
    'foo' => array(
         'allow_ip' => '1.2.3.4',
         'redirect_if_not' => site_url('goaway')
     )
)

然后,在您的钩子类(或函数)中匹配第一段(我的示例只是一个函数):

$CI = get_instance();
$CI->load-config('my_hook');
$protected_routes = $CI->config->item('protected_routes');
$segment = $CI->uri->segment(1); // foo
if (in_array($segment, $protected_routes)) {

   // grab $protected_routes[$segment] and work with it
}

这样做的好处是不会弄乱您的核心控制器,因为许多人使用它作为在方法之间共享代码的一种方式。但是,该挂钩将在每个请求上运行,这意味着将另外两个文件加载添加到引导程序。

我在大型 RESTful 服务上使用了 hook 方法,通过要求额外的标头来保护某些端点,并对其他端点实施不同类型的速率限制。请注意,上面的代码只是钩子的一个示例,而不是如何设置钩子本身。阅读 CI 手册的 hooks 部分,它非常简单直接。

最后,如果你真的想通过 来做.htaccess,你必须自己去请求。永远不会进入目录application/controllers/foo,实际请求是/foo/controller/method{args},这会导致 CI​​ 实例化foo/controller.php类。请记住,一旦重写,服务器会看到index.php?....

为此,您可以根据请求 URI 模式重新编写,如下所示(尚未测试,YMMV):

RewriteRule (^|/)foo(/|$) - [F,L]

可用于将访问虚拟路径的任何人重定向到受保护的控制器。这可能更可取,因为它可以防止 PHP 需要处理它,但是您失去了对匹配时发生的事情控制粒度。不过,如果您有多个敏感区域需要保护,您可以使用类似上述重写与钩子或核心实现相结合的方法。

于 2012-12-23T11:08:03.040 回答
1

Tim Post 的上述想法与我在此站点或其他地方看到的另一种方法相似。我花了一段时间才回到这个问题上,但终于完成了。

正如 TheShiftExchange 在我原来的问题下的评论中指出的那样,.htaccess 不适用于 Codeigniter 项目。以下是我最终得到的结果,并且似乎运行良好。它可能不是 100% 安全的,但我真的只是想从直接访问中删除这些页面。如果有人设法进入该页面,则仍然有一个用户/密码登录屏幕。

应用程序/配置中的新配置文件

switch (ENVIRONMENT) //set in index.php
{
    case 'development':
        $config['admin_ips'] = array('XXX.XXX.XXX.XXX');
        break;
    case 'testing':
        $config['admin_ips'] = array('XXX.XXX.XXX.XXX', 'XXX.XXX.XXX.XXX', 'XXX.XXX.XXX.XXX');
        break;
    case 'production':
        $config['admin_ips'] = array('XXX.XXX.XXX.XXX', 'XXX.XXX.XXX.XXX', 'XXX.XXX.XXX.XXX');
        break;
}

新控制器

class Admin_IP_Controller extends MY_Controller {
    function __construct()
    {
        parent::__construct();
        $this->load->config('admin_ips');
        if (!in_array($this->input->ip_address(), $this->config->item('admin_ips')))
        {
            show_404();
        }
    }
}
于 2013-01-11T22:07:42.713 回答