コントローラフィルタ

コントローラフィルタはで、コントローラ実行の前後にアクションを実行します。Unlike events, you can very simply choose which URI's in your application have the filters applied to them. 入力フィルタは Request を編集することができ、事後フィルタは Response も編集することができます。大きな柔軟性とパワーを持っています。フィルタが処理すべき一般的なタスク例をいくつか示します:

  • リクエスト受付時のCSRF 攻撃への防御
  • Restricting areas of your site based upon their Role
  • 特定エンドポイントのリクエスト制限
  • "ただいまメンテナンス中です" ページの表示
  • コンテントネゴシエーションの自動処理
  • などなど……

フィルタの作成

フィルタは CodeIgniter\Filters\FilterInterface を実装するシンプルなクラスです。 They contain two methods: before() and after() which hold the code that will run before and after the controller respectively. Your class must contain both methods but may leave the methods empty if they are not needed. フィルタクラスのスケルトンは次のようになります:

<?php namespace App\Filters;

use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;

class MyFilter implements FilterInterface
{
    public function before(RequestInterface $request)
    {
        // ここで何かをする
    }

    //--------------------------------------------------------------------

    public function after(RequestInterface $request, ResponseInterface $response)
    {
        // ここで何かをする
    }
}

事前フィルタ

どのフィルタでも $request オブジェクトを return することができ、現在の Request と差し替えられます。これによってコントローラの実行時に起きることを変更できます。

事前フィルタはコントローラの実行前に優先して実行されるので、コントローラが実行される前に処理を止めることもできます。そうするにはリクエストオブジェクト以外の何かを返してください。 This is typically used to perform redirects, like in this example:

public function before(RequestInterface $request)
{
    $auth = service('auth');

    if (!$auth->isLoggedIn())
    {
        return redirect('login');
    }
}

Response インスタンスが返されると、Response がクライアントに返送されスクリプトの実行は停止されます。 これは API の実行制限に有用です。See app/Filters/Throttle.php for an example.

事後フィルタ

事後フィルタは事前フィルタと似たようなものですが、$response オブジェクトしか返せないのと、スクリプトの停止ができない点が異なります。これは最終出力を編集することができます。言い換えると、単に最終出力を何かするだけです。便利にできることは、セキュリティヘッダが正しく設定されていることを確認すること、もしくは最終出力をキャッシュすること、あるいは最終出力に NG ワードフィルタをすることです。

Configuring Filters

フィルタを作ったなら、実行するには設定が必要です。This is done in app/Config/Filters.php. このファイルには、フィルタを実行する設定として4つのプロパティを持ちます。

$aliases

$aliases 配列は、実行するフィルタを1つ以上、クラス名を完全な形で記述した連想配列です:

public $aliases = [
    'csrf' => \CodeIgniter\Filters\CSRF::class
];

エイリアスは必須です。完全なクラス名をこのあとで使おうとすれば、システムはエラーを投げます。この方法で定義すれば、使用クラスを切り替えるのが単純になります。認証システムを別のものに変えようと判断したときにはすばらしいもので、フィルタクラスを別のものにすればおしまいになります。

複数のフィルタをひとつのエイリアスにつなげることも可能で、複雑なフィルタセットもシンプルにすることができます:

public $aliases = [
    'apiPrep' => [
        \App\Filters\Negotiate::class,
        \App\Filters\ApiAuth::class
    ]
];

必要な数のエイリアスを定義する必要があります。

$globals

2つ目のセクションでは、すべてのリクエストで有効になるフィルタを定義できます。 どれだけここに使うかは気をつける必要があります。毎回のリクエストで多くを実行しすぎれば、パフォーマンスに影響を与えるからです。before または after 配列にエイリアスを加えることでフィルタを指定できます:

public $globals = [
        'before' => [
                'csrf'
        ],
        'after'  => []
];

ほぼ毎回のリクエストで実行したいけれども、わずかだけ実行したくないということがあります。 一般的な例として、サードパーティのサイトから特定の1つ2つの URI を叩けるようにするため、CSRF 攻撃保護フィルタの例外とし、残りは保護したままとする必要があるとします。これをするには、'except' キーと URI 検索文字列を、エイリアスの値側の配列に加えます:

public $globals = [
        'before' => [
                'csrf' => ['except' => 'api/*']
        ],
        'after'  => []
];

フィルタ設定の URI の使える箇所ではどこでも、正規表現、もしくはこの例のようにアスタリスクをワイルドカードとしてその後の文字全部に一致するものとして使用できます。この例では api/ で始まる URL は CSRF 攻撃保護の対象外となりますが、サイトのフォームはすべて保護の対象となります。複数の URI を指定する必要があるなら、URI パターンを配列で指定できます:

public $globals = [
        'before' => [
                'csrf' => ['except' => ['foo/*', 'bar/*']]
        ],
        'after'  => []
];

$methods

フィルタには一定の HTTP メソッド、つまりPOST、GET、PUTなどのようなものを適用することができます。この配列では、メソッド名は小文字で指定します。この値はフィルタを実行したいものの配列です。$globals や他の $filters プロパティとは異なり、事前フィルタとしてのみ動作します:

public $methods = [
    'post' => ['foo', 'bar'],
    'get'  => ['baz']
]

標準的な HTTP メソッドに加え、次の特殊な2つをサポートします: 'cli' と 'ajax'です。見ての通りではありますが説明しますと、'cli' はコマンドラインからのリクエストで動作し、'ajax' はすべての AJAX リクエストに適用されます。

$filters

このプロパティはフィルタエイリアスの配列です。For each alias, you can specify before and after arrays that contain a list of URI patterns that filter should apply to:

public filters = [
    'foo' => ['before' => ['admin/*'], 'after' => ['users/*']],
    'bar' => ['before' => ['api/*', 'admin/*']]
];

Provided Filters

Three filters are bundled with CodeIgniter4: Honeypot, Security, and DebugToolbar.