ตรวจสอบว่าผู้ใช้มีการเข้าถึงหน้าใดหน้าหนึ่งหรือไม่


23

ฉันจะทราบได้อย่างไรว่าผู้ใช้มีสิทธิ์ในการเข้าถึงหน้าบางหน้า?


คุณไม่ได้ระบุรุ่นของ Drupal ที่คุณใช้ รายละเอียดเพิ่มเติมเกี่ยวกับเป้าหมายของคุณก็มีประโยชน์เช่นกัน ในกรณีส่วนใหญ่ Drupal จะจัดการการเข้าถึงเมนูโดยอัตโนมัติ
Dylan Tack

คำตอบ:


25

หากคุณต้องการตรวจสอบว่าผู้ใช้ที่เข้าสู่ระบบในปัจจุบันมีการเข้าถึงหน้าคุณสามารถใช้รหัสต่อไปนี้:

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

$path เป็นเส้นทางของหน้าเว็บที่คุณต้องการตรวจสอบ (เช่นโหนด / 1, ผู้ดูแลระบบ / ผู้ใช้ / ผู้ใช้)

รหัสที่ทำงานใน Drupal 6 และรุ่นที่สูงขึ้นและก็เป็นหนึ่งที่ใช้จากmenu_execute_active_handler ()

เหตุผลที่ฉันไม่แนะนำให้โทรไปที่ callback โดยตรงโดยตรงนั้นเป็นเพราะข้อโต้แย้งที่ต้องถูกส่งผ่านไปยังฟังก์ชั่นนั้น

รหัสที่ใช้โดย_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 ()ในกรณีนี้ใช้วัตถุผู้ใช้สำหรับผู้ใช้ที่เข้าสู่ระบบในปัจจุบัน ในกรณีที่สองหนึ่งในข้อโต้แย้งคือวัตถุโหนดที่ได้รับจาก URL; ตัวอย่างเช่นหาก URL คือ example.com/node/1 ดังนั้นอาร์กิวเมนต์ที่สองที่ส่งผ่านไปยัง callback access คือวัตถุโหนดสำหรับโหนดที่มี ID โหนดเท่ากับ 1
การเขียนรหัสที่จัดการกับกรณีเหล่านี้ก็จะหมายถึงรหัสที่ซ้ำกัน มีอยู่แล้วใน Drupal แม้ว่าคุณทำซ้ำรหัสนั้นจะยังคงมีปัญหาของการเรียกกลับที่กำลังตรวจสอบการเข้าถึงกับผู้ใช้ที่เข้าสู่ระบบในปัจจุบัน

หากคุณต้องการตรวจสอบว่าผู้ใช้ที่ไม่ใช่ผู้ใช้ที่เข้าสู่ระบบในปัจจุบันสามารถเข้าถึงเมนูคือการเปลี่ยนค่าของตัวแปรทั่วโลกครั้งแรก$userใช้รหัสฉันรายงานที่จุดเริ่มต้นของคำตอบของฉันแล้วเรียกคืนค่าของ$user. สำหรับวิธีการเปลี่ยนค่าของโลก$userที่คุณสามารถดูโปรแกรมปลอมตัวเป็นผู้ใช้รายอื่นโดยไม่ก่อให้เข้าสู่ระบบในขณะนี้ผู้ใช้จะออกจากระบบ ความแตกต่างคือแทนที่จะใช้ค่าที่ส่งกลับจากdrupal_anonymous_user () , คุณใช้ค่าที่ส่งกลับจากuser_load ()


ฉันขอทราบได้ไหมว่าควรเขียนโค้ดนี้ในตะขออะไร
Gladiator

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

เป็นเรื่องจริง แต่ใช้ได้สำหรับผู้ใช้ที่เข้าสู่ระบบในปัจจุบันเท่านั้น หากคุณต้องการทราบว่าผู้ใช้รายอื่นสามารถเข้าถึงพา ธdrupal_valid_pathได้หรือไม่จะไม่ช่วยคุณ
Andrew Schulman

@AndrewSchulman ฉันไม่คิดว่าจะมี API สำหรับสิ่งนั้น แต่คุณสามารถเปลี่ยนผู้ใช้ได้ชั่วคราว
peterpoe

ใน Drupal 8 สิ่งนี้ได้ย้ายไปที่\Drupal::service('path.validator')->isValid($path);- ดูเอกสาร API
Gogowitsch

3

โทรไปaccess callbackที่ระบุไว้ในรายการเมนูที่รับผิดชอบสำหรับหน้า รายการเมนูนั้นมักจะถูกสร้างขึ้นโดย Drupal เรียกการใช้งานhook_menuและถูกเก็บไว้ในฐานข้อมูล ระวังว่าข้อมูลที่ส่งกลับโดยอาจจะมีการเปลี่ยนแปลงได้โดยโมดูลการดำเนินการhook_menuhook_menu_alter

ระวังว่าบางโมดูลอาจไม่ผ่านผู้ใช้เป็นอาร์กิวเมนต์แยกต่างหาก (ตามที่ระบุโดยaccess argumentsคีย์ของรายการเมนู) แต่อาจใช้$userวัตถุร่วมแทน คุณจะต้องตรวจสอบสิ่งนี้สำหรับแต่ละโมดูลที่คุณใช้


วิธีนี้สามารถใช้เพื่อค้นหาว่าผู้ใช้อื่นที่ไม่ใช่ผู้ใช้ที่ทำหน้าที่ได้รับอนุญาตให้เข้าถึงหน้า
Oswald

1
การโทรกลับด้วยการโทรกลับไม่ใช่เรื่องง่ายเหมือนกับการเรียกฟังก์ชั่นอื่น ๆ เนื่องจากการโทรกลับเข้าถึงนั้นต้องการอาร์กิวเมนต์ที่เฉพาะเจาะจง ดู_menu_check_access ()ซึ่งเป็นฟังก์ชันที่ตรวจสอบว่าผู้ใช้ที่เข้าสู่ระบบในปัจจุบันสามารถเข้าถึงเมนูได้หรือไม่
kiamlaluno

2

ตรวจสอบuser_access()ฟังก์ชั่น ดูลิงค์สำหรับพารามิเตอร์ที่ระบุสำหรับแต่ละรุ่นของ Drupal จากหน้าเอกสารสำหรับ Drupal 7-8:

พารามิเตอร์

$ string การอนุญาตเช่น "การจัดการโหนด" กำลังถูกตรวจสอบ

บัญชี $ (ตัวเลือก) บัญชีที่จะตรวจสอบหากไม่ได้รับการใช้งานในปัจจุบันผู้ใช้เข้าสู่ระบบ

ค่าส่งคืน

บูลีน TRUE หากผู้ใช้ปัจจุบันมีสิทธิ์ที่ร้องขอ

การตรวจสอบสิทธิ์ทั้งหมดใน Drupal ควรผ่านฟังก์ชั่นนี้ ด้วยวิธีนี้เรารับประกันพฤติกรรมที่สอดคล้องกันและตรวจสอบให้แน่ใจว่า superuser สามารถดำเนินการทั้งหมดได้


user_access () ใช้สำหรับตรวจสอบว่าผู้ใช้มีสิทธิ์ "ประเภท" ที่แน่นอนหรือไม่ สิ่งที่จำเป็นคือถ้าผู้ใช้สามารถเข้าถึง "เส้นทาง" บางอย่างได้ ตัวอย่างเช่นหากผู้ใช้สามารถเข้าถึง 'node / 12'
Farzan

คุณจะทราบได้อย่างไรว่าผู้ใช้มีสิทธิ์หรือไม่? ฉันจะถือว่ามีตัวเลือกในหน้าสิทธิ์ที่คุณทั้งมีการตรวจสอบหรือไม่ที่จะให้บทบาทบางอย่างสิทธิ์
Laxman13

user_access()ไม่ใช่การเรียกกลับที่ใช้โดยเมนู user_access()แม้มันจะเป็นที่คุณควรรู้ข้อโต้แย้งการเข้าถึงที่คุณต้องผ่านไป
kiamlaluno

ฉันรู้ว่ามันไม่ได้เสมอ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.