Codeigniter拒绝使用apache配置访问控制器目录

时间:2012-12-05 23:02:36

标签: apache codeigniter apache-config

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

它与Codeigniter路由的方式有什么关系吗?或者,我离开了吗?

我正在使用的不起作用

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

2 个答案:

答案 0 :(得分: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 */
    }
}

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

此外,如果您不需要构造函数,则不需要在管理控制器中使用构造函数,因为如果未定义父元素,则构造父元素。如果你定义一个,请确保调用父。

您还可以将白名单放在数据库中,Redis,无论如何。

另一种方法是using hooks,特别是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
}

这样做的好处是不会使核心控制器混乱,因为许多人将其用作在方法之间共享代码的方法。但是,钩子将在每个请求上运行,这意味着将另外两个文件加载添加到bootstrap。

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

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

要实现这一点,您可以根据请求URI模式重写,如下所示(尚未测试,YMMV):

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

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

答案 1 :(得分:1)

Tim Post的上述想法与我在本网站或其他地方看到的另一种方法类似。我花了一段时间才回到这个问题,但最后它已经完成了。

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

application / config中的新配置文件

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();
        }
    }
}