CI で動作するように URL を書き直す方法が原因で、実際にindex.php?{args}
. フィルタリングする場合は、代わりに CI で行う必要があります。オプションは、コア コントローラーまたはフックです。
これを行う簡単な方法は、admin/area スクリプトが拡張するコア コントローラーを作成し、そこで 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 などに配置することもできます。
これを行う別の方法は、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
}
多くの人がメソッド間でコードを共有する手段としてコア コントローラーを使用しているため、これにはコア コントローラーが乱雑にならないという利点があります。ただし、フックはすべてのリクエストで実行されます。つまり、さらに 2 つのファイル ロードがブートストラップに追加されます。
大規模な RESTful サービスでフック メソッドを使用して、特定のエンドポイントを保護するために、追加のヘッダーを要求し、別の種類のレート制限を他のエンドポイントに適用しました。上記のコードは、フック自体を設定する方法ではなく、フックに入れることができるものの例にすぎないことに注意してください。CI マニュアルのフック セクションを読んでください。非常に簡単で簡単です。
最後に、本当に 経由で実行したい場合は.htaccess
、リクエスト自体を実行する必要があります。ディレクトリapplication/controllers/foo
が入力されることはありません。実際のリクエストは です/foo/controller/method{args}
。これにより、CI はfoo/controller.php
クラスをインスタンス化します。覚えておいてください、一度書き直されると、サーバーはindex.php?....
これを達成するために、次のようなリクエスト URI パターンに基づいて書き直すことができます (YMMV はテストしていません)。
RewriteRule (^|/)foo(/|$) - [F,L]
これは、仮想パスにアクセスするすべての人を保護されたコントローラーにリダイレクトするために使用できます。これは、PHP がそれを処理する必要がなくなるので好ましいかもしれませんが、一致した場合に何が起こるかを制御する粒度が失われます。それでも、保護する機密領域が複数ある場合は、フックまたはコアの実装と組み合わせて上記の書き換えのようなものを使用できます。