我想限制访问仅用于管理目的的控制器文件夹。我已经尝试了很多方法而没有提出解决方案。这些控制器支持密码保护。但是,如果有人偶然发现正确的目录,我想将其从视图中删除。可以这样做吗?我宁愿不从htaccess那里做。我可以访问apache配置文件,所以我想在那里处理它。
它与Codeigniter路由的方式有什么关系吗?或者,我离开了吗?
我正在使用的不起作用
<Directory /var/www/application/controllers/folder/>
Order deny,allow
Deny from all
Allow from xxx.xxx.xxx.xxx
</Directory>
答案 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();
}
}
}