ユーザーが特定のページにアクセスできるかどうかを確認します


23

ユーザーが特定のページにアクセスする権限を持っているかどうかを確認するにはどうすればよいですか?


使用するDrupalのバージョンを指定しませんでした。目標に関する詳細も役立ちます。最も一般的な場合、Drupalはメニューアクセスを自動的に処理します。
ディランタック

回答:


25

現在ログインしているユーザーがページにアクセスできるかどうかを確認する場合は、次のコードを使用できます。

if ($router_item = menu_get_item($path)) {
  if ($router_item['access']) {
    // The user has access to the page in $path.
  }
}

$path チェックしたいページのパスです(例えば、node / 1、admin / user / user)。

このコードはDrupal 6以降のバージョンで動作し、menu_execute_active_handler()から使用されるものです

アクセスコールバックを直接呼び出すことを提案していないのは、その関数に渡す必要がある引数があるためです。

_menu_check_access()で使用されるコードは次のとおりです(Drupal 7):

$arguments = menu_unserialize($item['access_arguments'], $map);
// As call_user_func_array is quite slow and user_access is a very common
// callback, it is worth making a special case for it.
if ($callback == 'user_access') {
  $item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]);
}
elseif (function_exists($callback)) {
  $item['access'] = call_user_func_array($callback, $arguments);
}

コードは可能な限り汎用的である必要がありますが、ユーザーオブジェクトを直接処理しません。つまり、現在ログインしているユーザーのユーザーオブジェクトを別のユーザーオブジェクトに置き換えることはできません。
コードは、次のようなメニュー定義を処理するのに十分な汎用性が必要です。

$items['node/add/' . $type_url_str] = array(
  'title' => $type->name, 
  'title callback' => 'check_plain', 
  'page callback' => 'node_add', 
  'page arguments' => array($type->type), 
  'access callback' => 'node_access', 
  'access arguments' => array('create', $type->type), 
  'description' => $type->description, 
  'file' => 'node.pages.inc',
);

$items['node/%node'] = array(
  'title callback' => 'node_page_title', 
  'title arguments' => array(1),
  // The page callback also invokes drupal_set_title() in case
  // the menu router's title is overridden by a menu link. 
  'page callback' => 'node_page_view', 
  'page arguments' => array(1), 
  'access callback' => 'node_access', 
  'access arguments' => array('view', 1),
);

どちらの定義でも、アクセス引数にはユーザーオブジェクトが含まれていません。この場合、node_access()は現在ログインしているユーザーのユーザーオブジェクトを使用します。2番目の場合、引数の1つはURLから取得されるノードオブジェクトです。たとえば、URLがexample.com/node/1の場合、アクセスコールバックに渡される2番目の引数は、ノードIDが1のノードのノードオブジェクトです。
これらのケースも処理するコードを記述すると、コードが重複することになりますDrupalに既に存在します。そのコードを複製したとしても、現在ログインしているユーザーに対してアクセスをチェックしているアクセスコールバックの問題が残っています。

現在ログインしているユーザーではないユーザーがメニューにアクセスできるかどうかを確認する場合は、最初にグローバル変数の値を変更し$user、回答の冒頭で報告したコードを使用してから、$user。globalの値を変更する方法については、現在ログインしているユーザーをログアウトさせることなく、プログラムで別のユーザーになりすます$userことができます。違いは、drupal_anonymous_user()から返された値を使用する代わりに、user_load()から返された値を使用することです。


このコードをどのフックに書くべきかを知ってください。
剣闘士

14

drupal_valid_path()を試してください。

関数が返すのTRUEは、引数が存在するときに渡されたパスであり、現在のユーザーはそれにアクセスできます。したがって、Drupal 7で作業していて、現在ログインしているユーザーのアクセスを確認する必要がある場合は、最も簡単な方法です。

if (drupal_valid_path('my/path')) {
  // Your code here...
}

1
D7 drupal_valid_pathでは、仕事を完璧にこなし、この正確なニーズを満たすように作られています。menu_get_itemを使用し、アクセスもチェックします。
Weboide 14

それは事実ですが、現在ログインしているユーザーに対してのみ機能します。他のユーザーがパスにアクセスできるかどうかを知りたい場合drupal_valid_pathは、役に立ちません。
アンドリューシュルマン

@AndrewSchulmanそのためのAPIはないと思いますが、一時的にユーザーを切り替えることができます。
ペテルポエ

Drupal 8では、これはAPIドキュメントを\Drupal::service('path.validator')->isValid($path);参照してください
-Gogowitsch

3

access callbackページを担当するメニューエントリで指定されているを呼び出します。そのメニューエントリは通常、Drupalの実装を呼び出すことで作成さhook_menuれ、データベースのどこかに保存されます。によって返されるデータは、をhook_menu実装するモジュールによって変更される可能性があることに注意してくださいhook_menu_alter

一部のモジュールaccess argumentsは、(メニューエントリのキーで指定された)別の引数としてユーザーを渡さないかもしれませんが、代わりにグローバル$userオブジェクトを代わりに使用するかもしれないことに注意してください。使用するモジュールごとにこれを確認する必要があります。


このメソッドを使用して、演技ユーザー以外のユーザーがページへのアクセスを許可されているかどうかを確認できます。
オズワルド

1
アクセスコールバックは特定の引数を必要とするため、アクセスコールバックの呼び出しは他の関数の呼び出しほど簡単ではありません。_menu_check_access()を参照してください。これは、現在ログインしているユーザーがメニューにアクセスできるかどうかを確認する関数です。
キアムルノ

2

機能をチェックしてくださいuser_access()。Drupalの各バージョンに指定されたパラメーターのリンクを参照してください。Drupal 7-8のドキュメントページから:

パラメーター

$ string「ノードの管理」などのチェック対象のアクセス許可。

$ account(オプション)指定されていない場合、現在ログインしているユーザーの使用を確認するアカウント。

戻り値

現在のユーザーが要求された権限を持っている場合、ブール値TRUE。

Drupalのすべての許可チェックは、この機能を通過する必要があります。このようにして、一貫した動作を保証し、スーパーユーザーがすべてのアクションを実行できるようにします。


user_access()は、ユーザーが特定の「タイプ」の許可を持っているかどうかを確認するためのものです。必要なのは、ユーザーが特定の「パス」にアクセスできる場合です。たとえば、ユーザーが「node / 12」にアクセスできる場合
ファルザン

さて、ユーザーがいつ許可を得るかをどのように決定しますか?特定のロールにアクセス許可を付与するためにチェックしたかしないかのアクセス許可ページにオプションがあると仮定します
Laxman13

user_access()メニューで使用されるアクセスコールバックとは限りません。たとえそうであっても、に渡す必要があるアクセス引数を知っている必要がありますuser_access()
キアムルノ

私はそれが常にuser_access()ではないことを知っている、OPがユーザーがアクセスする必要があるかどうかを確認する許可を念頭に置いていたと考えた。あまり説明的な質問ではありません
Laxman13

user_accessは特定のパスへのアクセスをチェックすることはできませんが、可能な限りuser_accessを使用することがアクセスをチェックする最善の方法だと思います。@ Laxman13 +1の良い答え。
AyeshK

2

ユーザーが特定のノードにアクセスできるかどうかを知る必要があり、ノードアクセスモジュールを使用している場合は、node_access()を使用できます。(ノードアクセスモジュールなしでは、「コンテンツへのアクセス」権限のみが必要です。)

ユーザーがhook_menu()実装によって定義された任意のパスにアクセスできるかどうかを把握したい場合、データベースからメニューエントリを取得し、その「アクセスコールバック」パラメータを評価する必要があります。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.