0 フォロワー

フィルター

フィルターは、コントローラアクションの前または後、あるいはその両方で実行されるオブジェクトです。例えば、アクセス制御フィルターは、特定のエンドユーザーがアクセスすることを許可されているか確認するためにアクションの前に実行される場合があります。コンテンツ圧縮フィルターは、エンドユーザーに送信する前にレスポンスコンテンツを圧縮するためにアクションの後に実行される場合があります。

フィルターは、プリフィルター(アクションに適用されるフィルタリングロジック)および/またはポストフィルター(アクションに適用されるロジック)で構成される場合があります。

フィルターの使用

フィルターは基本的に特別な種類のビヘイビアです。したがって、フィルターの使用はビヘイビアの使用と同じです。次の例のように、コントローラクラスでbehaviors()メソッドをオーバーライドすることでフィルターを宣言できます。

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\HttpCache',
            'only' => ['index', 'view'],
            'lastModified' => function ($action, $params) {
                $q = new \yii\db\Query();
                return $q->from('user')->max('updated_at');
            },
        ],
    ];
}

デフォルトでは、コントローラクラスで宣言されたフィルターは、そのコントローラのすべてのアクションに適用されます。ただし、onlyプロパティを設定することで、フィルターを適用する必要があるアクションを明示的に指定できます。上記の例では、HttpCacheフィルターはindexアクションとviewアクションにのみ適用されます。また、exceptプロパティを設定して、一部のアクションがフィルタリングされないようにすることもできます。

コントローラに加えて、モジュールまたはアプリケーションでフィルターを宣言することもできます。そうすると、フィルターのonlyプロパティとexceptプロパティを上記のように設定しない限り、フィルターは、そのモジュールまたはアプリケーションに属するすべてのコントローラアクションに適用されます。

注: モジュールまたはアプリケーションでフィルターを宣言する場合は、onlyプロパティとexceptプロパティでアクションIDの代わりにルートを使用する必要があります。これは、アクションIDだけでは、モジュールまたはアプリケーションの範囲内のアクションを完全に指定できないためです。

単一のアクションに対して複数のフィルターが設定されている場合、以下で説明するルールに従って適用されます。

  • プリフィルタリング
    • アプリケーションで宣言されたフィルターを、behaviors()にリストされている順序で適用します。
    • モジュールで宣言されたフィルターを、behaviors()にリストされている順序で適用します。
    • コントローラで宣言されたフィルターを、behaviors()にリストされている順序で適用します。
    • いずれかのフィルターがアクションの実行をキャンセルした場合、その後のフィルター(プリフィルターとポストフィルターの両方)は適用されません。
  • プリフィルタリングに合格した場合のアクションの実行。
  • ポストフィルタリング
    • コントローラで宣言されたフィルターを、behaviors()にリストされている逆順で適用します。
    • モジュールで宣言されたフィルターを、behaviors()にリストされている逆順で適用します。
    • アプリケーションで宣言されたフィルターを、behaviors()にリストされている逆順で適用します。

フィルターの作成

新しいアクションフィルターを作成するには、yii\base\ActionFilter を拡張し、beforeAction() メソッドや afterAction() メソッドをオーバーライドします。前者はアクションが実行される前に実行され、後者はアクションが実行された後に実行されます。beforeAction() の戻り値は、アクションを実行するかどうかを決定します。もし false であれば、このフィルター以降のフィルターはスキップされ、アクションは実行されません。

次の例は、アクションの実行時間をログに記録するフィルターを示しています。

namespace app\components;

use Yii;
use yii\base\ActionFilter;

class ActionTimeFilter extends ActionFilter
{
    private $_startTime;

    public function beforeAction($action)
    {
        $this->_startTime = microtime(true);
        return parent::beforeAction($action);
    }

    public function afterAction($action, $result)
    {
        $time = microtime(true) - $this->_startTime;
        Yii::debug("Action '{$action->uniqueId}' spent $time second.");
        return parent::afterAction($action, $result);
    }
}

コアフィルター

Yiiは、主に yii\filters 名前空間にある、よく使われるフィルターのセットを提供しています。以下では、これらのフィルターを簡単に紹介します。

AccessControl

AccessControlは、ルールのセットに基づいた簡単なアクセス制御を提供します。特に、アクションが実行される前に、AccessControlはリストされたルールを調べ、現在のコンテキスト変数(ユーザーIPアドレス、ユーザーログイン状態など)に一致する最初のルールを見つけます。一致するルールによって、要求されたアクションの実行を許可するか拒否するかが決まります。一致するルールがない場合は、アクセスは拒否されます。

次の例は、認証済みのユーザーに create および update アクションへのアクセスを許可し、他のすべてのユーザーがこれらの2つのアクションにアクセスすることを拒否する方法を示しています。

use yii\filters\AccessControl;

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::class,
            'only' => ['create', 'update'],
            'rules' => [
                // allow authenticated users
                [
                    'allow' => true,
                    'roles' => ['@'],
                ],
                // everything else is denied by default
            ],
        ],
    ];
}

一般的なアクセス制御の詳細については、認証のセクションを参照してください。

認証メソッドフィルター

認証メソッドフィルターは、HTTP Basic AuthOAuth 2などのさまざまなメソッドを使用してユーザーを認証するために使用されます。これらのフィルタークラスはすべて、yii\filters\auth 名前空間にあります。

次の例は、HTTP Basic Authメソッドに基づいてアクセストークンを使用してユーザーを認証するために、yii\filters\auth\HttpBasicAuth をどのように使用できるかを示しています。これが機能するためには、ユーザーアイデンティティクラスfindIdentityByAccessToken()メソッドを実装している必要があることに注意してください。

use yii\filters\auth\HttpBasicAuth;

public function behaviors()
{
    return [
        'basicAuth' => [
            'class' => HttpBasicAuth::class,
        ],
    ];
}

認証メソッドフィルターは、RESTful APIの実装でよく使用されます。詳細については、RESTfulの認証セクションを参照してください。

ContentNegotiator

ContentNegotiatorは、レスポンスフォーマットのネゴシエーションとアプリケーション言語のネゴシエーションをサポートします。GET パラメータと Accept HTTPヘッダーを調べることにより、レスポンスフォーマットや言語を決定しようとします。

次の例では、ContentNegotiatorはJSONおよびXMLレスポンスフォーマット、および英語(米国)とドイツ語をサポートするように構成されています。

use yii\filters\ContentNegotiator;
use yii\web\Response;

public function behaviors()
{
    return [
        [
            'class' => ContentNegotiator::class,
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
                'application/xml' => Response::FORMAT_XML,
            ],
            'languages' => [
                'en-US',
                'de',
            ],
        ],
    ];
}

レスポンスフォーマットと言語は、アプリケーションライフサイクルの早い段階で決定する必要があることがよくあります。このため、ContentNegotiatorはフィルターとして使用できるだけでなく、ブートストラップコンポーネントとしても使用できるように設計されています。たとえば、次の例のように、アプリケーション構成で構成することができます。

use yii\filters\ContentNegotiator;
use yii\web\Response;

[
    'bootstrap' => [
        [
            'class' => ContentNegotiator::class,
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
                'application/xml' => Response::FORMAT_XML,
            ],
            'languages' => [
                'en-US',
                'de',
            ],
        ],
    ],
];

情報:リクエストから優先されるコンテンツタイプと言語を決定できない場合、formatslanguages にリストされている最初のフォーマットと言語が使用されます。

HttpCache

HttpCacheは、Last-Modified および Etag HTTPヘッダーを利用して、クライアント側のキャッシュを実装します。たとえば、

use yii\filters\HttpCache;

public function behaviors()
{
    return [
        [
            'class' => HttpCache::class,
            'only' => ['index'],
            'lastModified' => function ($action, $params) {
                $q = new \yii\db\Query();
                return $q->from('user')->max('updated_at');
            },
        ],
    ];
}

HttpCacheの使用に関する詳細については、HTTPキャッシュセクションを参照してください。

PageCache

PageCacheは、ページ全体のサーバーサイドキャッシングを実装します。次の例では、PageCacheは index アクションに適用され、最大60秒間、または post テーブルのエントリ数が変更されるまで、ページ全体をキャッシュします。また、選択されたアプリケーション言語に応じて、異なるバージョンのページを保存します。

use yii\filters\PageCache;
use yii\caching\DbDependency;

public function behaviors()
{
    return [
        'pageCache' => [
            'class' => PageCache::class,
            'only' => ['index'],
            'duration' => 60,
            'dependency' => [
                'class' => DbDependency::class,
                'sql' => 'SELECT COUNT(*) FROM post',
            ],
            'variations' => [
                \Yii::$app->language,
            ]
        ],
    ];
}

PageCacheの使用に関する詳細については、ページキャッシングセクションを参照してください。

RateLimiter

RateLimiterは、リーキーバケットアルゴリズムに基づいてレート制限アルゴリズムを実装します。これは主に、RESTful APIの実装で使用されます。このフィルターの使用に関する詳細については、レート制限セクションを参照してください。

VerbFilter

VerbFilterは、HTTPリクエストメソッドがリクエストされたアクションで許可されているかどうかを確認します。許可されていない場合は、HTTP 405例外をスローします。次の例では、VerbFilterは、CRUDアクションに対して許可される典型的なリクエストメソッドのセットを指定するために宣言されています。

use yii\filters\VerbFilter;

public function behaviors()
{
    return [
        'verbs' => [
            'class' => VerbFilter::class,
            'actions' => [
                'index'  => ['get'],
                'view'   => ['get'],
                'create' => ['get', 'post'],
                'update' => ['get', 'put', 'post'],
                'delete' => ['post', 'delete'],
            ],
        ],
    ];
}

Cors

クロスオリジンリソース共有 CORS は、Webページ上の多くのリソース(フォント、JavaScriptなど)が、リソースの発信元ドメイン以外の別のドメインから要求できるようにするメカニズムです。特に、JavaScriptのAJAX呼び出しは、XMLHttpRequestメカニズムを使用できます。このような「クロスドメイン」リクエストは、同一オリジンセキュリティポリシーによってWebブラウザーで禁止されます。CORSは、ブラウザとサーバーがクロスオリジンリクエストを許可するかどうかを決定するために相互作用できる方法を定義します。

Corsフィルターは、CORSヘッダーが常に送信されるように、認証/認可フィルターの前に定義する必要があります。

use yii\filters\Cors;
use yii\helpers\ArrayHelper;

public function behaviors()
{
    return ArrayHelper::merge([
        [
            'class' => Cors::class,
        ],
    ], parent::behaviors());
}

APIでyii\rest\ActiveControllerクラスにCORSフィルターを追加する場合は、RESTコントローラーに関するセクションも確認してください。

Corsフィルタリングは、$corsプロパティを使用して調整できます。

  • cors['Origin']:許可されたオリジンを定義するために使用される配列。['*'](すべて)または ['https://www.myserver.net', 'https://www.myotherserver.com'] にすることができます。デフォルトは ['*'] です。
  • cors['Access-Control-Request-Method']['GET', 'OPTIONS', 'HEAD'] のような許可された動詞の配列。デフォルトは ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'] です。
  • cors['Access-Control-Request-Headers']:許可されたヘッダーの配列。['*'] すべてのヘッダー、または特定のヘッダー ['X-Request-With'] にすることができます。デフォルトは ['*'] です。
  • cors['Access-Control-Allow-Credentials']:現在のリクエストを資格情報を使用して行うことができるかどうかを定義します。truefalse、またはnull(設定されていない)にすることができます。デフォルトはnullです。
  • cors['Access-Control-Max-Age']:プリフライトリクエストの有効期間を定義します。デフォルトは 86400 です。

たとえば、オリジン https://www.myserver.net でメソッド GETHEADOPTIONS でCORSを許可する場合。

use yii\filters\Cors;
use yii\helpers\ArrayHelper;

public function behaviors()
{
    return ArrayHelper::merge([
        [
            'class' => Cors::class,
            'cors' => [
                'Origin' => ['https://www.myserver.net'],
                'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
            ],
        ],
    ], parent::behaviors());
}

アクションごとにデフォルトのパラメータをオーバーライドして、CORSヘッダーを調整できます。たとえば、login アクションに Access-Control-Allow-Credentials を追加するには、次のようにします。

use yii\filters\Cors;
use yii\helpers\ArrayHelper;

public function behaviors()
{
    return ArrayHelper::merge([
        [
            'class' => Cors::class,
            'cors' => [
                'Origin' => ['https://www.myserver.net'],
                'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
            ],
            'actions' => [
                'login' => [
                    'Access-Control-Allow-Credentials' => true,
                ]
            ]
        ],
    ], parent::behaviors());
}

タイプミスを見つけたり、このページを改善する必要があると思われる場合は?
githubで編集 !