[Drupal]カスタムの権限を追加する方法・カスタム権限を使うメリット


Drupal3年やってきてはじめて知ったんですが、カスタム権限の追加方法が案外簡単だったので紹介したいと思います。

カスタム権限の作り方

静的権限の作り方

カスタムモジュールのルートにmy_module.permissions.ymlを作成し、以下のように記入してdrush crするだけ

display xxx:
  title: 'xxxを表示する'
  description: 'xxxを表示します.'
  restrict access: true

動的権限の作り方

権限名の中に変数を入れたい場合はこちらの方法を参照

権限の使い方

役割ごとに権限を割り当てる

作成した権限は/admin/people/permissions に表示されるので、この権限を適用したい役割にチェックして保存

権限チェックを行う

// 現在のユーザーを取得.
$user = \Drupal::getCurrentUser();
if ($user->hasPermission('display xxx')) {
  // 処理.
}

カスタム権限を使うメリット

コードの可読性が高くなる

「ユーザーが〇〇の役割を持っている場合はXXをできる」という要件をコード化する際、

役割で直接指定する場合

hook_entity_presaveなどで役割チェックしたい対象のユーザーの情報(UserInterface)をもともと持っている場合は単純に以下のように書ける。

if ($user->hasRole('editor')) {
  // 処理
}

ユーザー情報ではなくアカウント情報(AccountInterface)から役割を取得する場合は以下のようになる。(アカウント情報はgetRoles()はあってもhasRoleが無いのでコードが冗長になる。)

$user = \Drupal::currentUser();
if (in_array('editor', $user->getRoles()) {
  // 処理
}

もしくは

use Drupal\user\Entity\User
$account = \Drupal::currentUser();
$user = User::load($account->id());
if ($user->hasRole('editor')) {
  // 処理
}

権限で指定する場合

ユーザー情報でもアカウント情報でもhasPermission()が使える。

$user = \Drupal::currentUser();
if ($user->hasPermission('display xxx')) {
  // 処理
}

常に権限で指定するようにすればアカウント情報を使うときもコードがすっきりするし、役割よりも直接的でわかりやすい。

システムの見通しがよくなる

上記のように役割ベースで処理を分けた場合はソースコードを見ないと実際に誰が何をできるのかがわからないけど、権限ベースにした場合、管理画面から「どんな権限が」「どの役割に割り当てられているか」が確認できる。

権限と役割を分離できる

  • 権限: XXXをできるかどうか
  • 役割: 単なる人のグループ

として、いきなり「役割→処理」じゃなくて「役割→権限→処理」とワンクッション置くことになる。それによって「○○だけでなく△△の役割の人もXXできるようにしてください」と言われたときにコードをいじることなく役割と権限の紐付けだけ変えればいい等のメリットがある。

(システム開発では何事もワンクッション置く方がいい気がする)

個人的に、とある大規模システムで役割ベースで処理を書きまくった結果、誰が何をできるかパッと思い出せないという状況になってしまって後悔中なので、今後はできるだけカスタム権限を取り入れていきたい所存。