Kiểm tra xem người dùng có quyền truy cập vào một trang nhất định không


23

Làm cách nào để xác định xem người dùng có quyền truy cập vào một trang nhất định không?


Bạn đã không chỉ định phiên bản Drupal nào bạn sử dụng. Thêm chi tiết về mục tiêu của bạn cũng sẽ hữu ích; trong những trường hợp phổ biến nhất, Drupal sẽ tự động xử lý truy cập menu.
Dylan Tack

Câu trả lời:


25

Nếu bạn muốn xác minh xem người dùng hiện đang đăng nhập có quyền truy cập vào một trang hay không, bạn có thể sử dụng mã sau:

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

$path là đường dẫn của trang bạn muốn kiểm tra (ví dụ: nút / 1, quản trị viên / người dùng / người dùng).

Mã này hoạt động trong Drupal 6 và các phiên bản cao hơn, và nó là mã được sử dụng từ menu_execute_active_handler () .

Lý do tôi không đề nghị gọi trực tiếp cuộc gọi lại truy cập là vì các đối số cần được truyền cho hàm đó.

Mã được sử dụng bởi _menu_check_access () là đoạn mã sau (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);
}

Mã cần chung chung nhất có thể, không trực tiếp xử lý đối tượng người dùng. Điều này có nghĩa là không thể thay thế đối tượng người dùng cho người dùng hiện đang đăng nhập bằng một đối tượng người dùng khác.
Mã phải đủ chung chung để xử lý các định nghĩa menu như sau:

$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),
);

Trong cả hai định nghĩa, các đối số truy cập không bao gồm một đối tượng người dùng và node_access () trong trường hợp này sử dụng đối tượng người dùng cho người dùng hiện đang đăng nhập. Trong trường hợp thứ hai, một trong các đối số là đối tượng nút được lấy từ URL; ví dụ: nếu URL là example.com/node/1, thì đối số thứ hai được truyền cho cuộc gọi lại truy cập là đối tượng nút cho nút có ID nút bằng 1.
Viết mã xử lý các trường hợp này cũng có nghĩa là sao chép mã đã tồn tại ở Drupal. Ngay cả khi bạn đã sao chép mã đó, vẫn sẽ có vấn đề về các cuộc gọi lại truy cập đang kiểm tra quyền truy cập đối với người dùng hiện đang đăng nhập.

Nếu bạn muốn kiểm tra xem người dùng không phải là người dùng hiện đang đăng nhập có thể truy cập menu trước tiên để thay đổi giá trị của biến toàn cục hay không $user, hãy sử dụng mã tôi đã báo cáo ở đầu câu trả lời của tôi, sau đó khôi phục giá trị của $user. Để biết cách thay đổi giá trị toàn cầu $user, bạn có thể thấy lập trình mạo danh người dùng khác mà không khiến người dùng đăng nhập hiện tại phải đăng xuất . Sự khác biệt là, thay vì sử dụng giá trị được trả về từ drupal_anonymous_user () , bạn sử dụng giá trị được trả về từ user_load () .


Tôi có thể biết trong đó hook nên viết mã này.
Đấu sĩ

14

Hãy thử drupal_valid_path () .

Hàm trả về TRUElà đường dẫn được truyền dưới dạng đối số tồn tại và người dùng hiện tại có quyền truy cập vào nó. Vì vậy, nếu bạn đang làm việc trên Drupal 7 và bạn cần kiểm tra quyền truy cập trên người dùng hiện đang đăng nhập, đó là cách dễ nhất để đi:

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

1
Trong D7, drupal_valid_pathcông việc hoàn hảo và được thực hiện để đáp ứng nhu cầu chính xác này. Nó sử dụng menu_get_item và kiểm tra quyền truy cập.
Weboide

Điều đó đúng, nhưng nó chỉ hoạt động cho người dùng hiện đang đăng nhập. Nếu bạn muốn biết liệu một số người dùng khác có thể truy cập vào đường dẫn hay không, drupal_valid_pathsẽ không giúp bạn.
Andrew Schulman

@AndrewSchulman Tôi không nghĩ có API cho điều đó, nhưng bạn có thể tạm thời chuyển người dùng.
peterpoe

Trong Drupal 8, điều này đã được chuyển sang \Drupal::service('path.validator')->isValid($path);- xem tài liệu API
Gogowitsch

3

Gọi access callbackcái được chỉ định trong mục menu chịu trách nhiệm cho trang. Mục trình đơn đó thường được tạo bởi Drupal gọi việc thực hiện hook_menuvà được lưu trữ ở đâu đó trong cơ sở dữ liệu. Coi chừng dữ liệu được trả về hook_menucó thể bị thay đổi bởi mô đun triển khai hook_menu_alter.

Lưu ý rằng một số mô-đun có thể không vượt qua người dùng dưới dạng đối số riêng biệt (như được chỉ định bởi access argumentskhóa của mục nhập menu), nhưng thay vào đó có thể sử dụng $userđối tượng toàn cục . Bạn sẽ phải kiểm tra điều này cho từng mô-đun mà bạn sử dụng.


Phương pháp này có thể được sử dụng để tìm hiểu xem một số người dùng khác ngoài người dùng diễn xuất có được phép truy cập trang hay không.
Oswald

1
Gọi gọi lại truy cập không dễ như gọi bất kỳ chức năng nào khác, vì gọi lại truy cập cần các đối số cụ thể; xem _menu_check_access () , đây là chức năng kiểm tra xem người dùng hiện đang đăng nhập có quyền truy cập vào menu hay không.
kiamlaluno

2

Kiểm tra user_access()chức năng. Xem liên kết để biết các thông số được chỉ định cho từng phiên bản của Drupal. Từ trang tài liệu cho Drupal 7-8:

Thông số

$ string Quyền, chẳng hạn như "nút quản trị", đang được kiểm tra.

$ tài khoản (tùy chọn) Tài khoản cần kiểm tra, nếu không được sử dụng hiện đang đăng nhập người dùng.

Giá trị trả về

Boolean TRUE nếu người dùng hiện tại có quyền yêu cầu.

Tất cả các kiểm tra quyền trong Drupal phải đi qua chức năng này. Bằng cách này, chúng tôi đảm bảo hành vi nhất quán và đảm bảo rằng siêu người dùng có thể thực hiện tất cả các hành động.


user_access () là để kiểm tra xem người dùng có "loại" quyền nhất định hay không. Điều cần thiết là nếu người dùng có thể truy cập vào một "đường dẫn" nhất định; ví dụ: nếu người dùng có thể truy cập 'nút / 12'?
farzan

Làm thế nào để bạn xác định khi người dùng có được phép hay không? Tôi cho rằng có một tùy chọn trên trang quyền mà bạn đã kiểm tra hoặc không cho phép một số vai trò nhất định
Laxman13

user_access()không phải luôn luôn là cuộc gọi lại truy cập được sử dụng bởi một menu; thậm chí nó sẽ là, bạn nên biết các đối số truy cập mà bạn cần chuyển đến user_access().
kiamlaluno

Tôi biết không phải lúc nào cũng vậy user_access(), chỉ cần hình dung OP có quyền để kiểm tra xem người dùng có nên truy cập hay không. Không phải là một câu hỏi rất mô tả
Laxman13

Mặc dù user_access không thể kiểm tra quyền truy cập vào một đường dẫn cụ thể, tôi nghĩ rằng sử dụng user_access bất cứ khi nào có thể là cách tốt nhất để kiểm tra quyền truy cập. Câu trả lời hay @ Laxman13 +1.
AyeshK

2

Nếu bạn cần biết liệu người dùng có thể truy cập vào một nút cụ thể hay không và đang sử dụng mô-đun truy cập nút, bạn có thể sử dụng node_access () . (không có mô-đun truy cập nút, họ chỉ cần có quyền 'truy cập nội dung'.)

Nếu bạn muốn tìm hiểu xem người dùng có thể truy cập một đường dẫn tùy ý được xác định bởi triển khai hook_menu () hay không, bạn có thể phải truy xuất mục nhập menu từ cơ sở dữ liệu và đánh giá tham số 'truy cập gọi lại' của nó.


2
    $node = node_load(123);

    $account = user_load(456);

    if (node_access("update", $node, $account) === TRUE) 
   {

         print "access";    
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.