web-dev-qa-db-ja.com

再利用可能な方法で複雑なアクセス制御を記述する

私たちは、母親と父親という2つの重要な特性を持つ人間を表すノードを扱います。

両親だけでなく、叔母や叔父も、特定の表示モードであなたを見たり、非公開の画像を見たりするなど、追加の権限を取得する必要があります。

この複雑なアクセス制御は、いくつかのコントローラーとフックで簡単に呼び出せる方法でどこに配置する必要がありますか?

これからプログラムする機能に名前はありますか?

より良いアイデアがない場合は、検証を使用します。次のように使用するバリデーターにアクセス制御を置くことができます:

$errors = $family_access_validator->validate($node);
if (count($errors) > 0) {
    throw new AccessDeniedHttpException();
}

ただし、これが正しいアプローチかどうかはわかりません。検証を使用する場合、常にメッセージに関心がありますwhyデータは拒否されます。ここでは、OKかOKのみに関心があります。

2
Philipp Zedler

ルートのアクセス制御については、AccessInterfaceを実装するサービスを作成できます。簡単に言うと、これは単一のメソッドpublic function access(AccountInterface $account)を使用してモジュールのsrc/Accessフォルダーに配置されたクラスであり、AccessResultのフレーバーを返します。次に、モジュールのservices.ymlにクラスを登録し、そのアクセスチェッカーを使用するルートに注釈を付けるだけで、Drupalが残りの作業を行います。 関連ドキュメント

ドキュメントは、アクセスチェックされるルートに{node}のようなアップキャストされたパラメーターがある場合、関数の引数に$nodeを追加できることを示唆しています。つまり、public function access(AccountInterface $account, Node $node)であり、自動的に提供されます。私は実際にその部分を実際に試したことはありません。正常に機能していると想定すると、通常どおりにノードのフィールドにアクセスして、mother/fatherフィールドのエンティティIDを$accountが属するユーザーと比較できます。

異なるビューモードでエンティティを表示するためにこの同じアクセスチェックを自動的に呼び出す同様の方法があるかどうかはわかりませんが、結局のところ、これは他のサービスと同じなので、いつでもコンテナーからリクエストできますまたは、必要な他のコントローラ/サービス/フックに挿入します。これらのコンテキストでは、もちろん、現在のユーザー$accountと関連する$nodeを「手動で」確認して確認する必要があります。

5
stevekeiretsu

この複雑なアクセス制御は、いくつかのコントローラーとフックで簡単に呼び出せるようにどこに配置すればよいですか?

プログラムする予定の機能に名前はありますか?

あなたが探している用語/概念は Service です:

Drupal 8は、再利用可能な機能を分離するためのサービスの概念を導入し、これらのサービスをサービスコンテナーに登録することにより、これらのサービスをプラグインおよび置き換え可能にします。開発者は、Drupal)によって提供されるサービスにサービスコンテナー経由でアクセスして、これらのシステムの分離された性質が尊重されるようにすることをお勧めします。

上記のリンクは、サービスを作成する方法と、静的および依存性注入の両方でサービスコンテナーを介してサービスにアクセスする方法を詳しく説明しています。

これらのメソッドを理解すると、コントローラー、フック、プラグイン、その他のサービスなどで機能を簡単に再利用できるようになります。

4
Clive