欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

drupal 7 hook_node_grants hook_node_access_records 作用 示例 通义 merlin chatgpt 有大用 有大大用

drupal7 access control    

判断是否满足某个操作权限 "view" "update" "delete" "create"

node_access($op, $node, $account = NULL);
   

定制NODE访问权

定制权限需要使用hook_node_access_records与hook_node_grants
hook_node_grants为每个user定义realm和gid
hook_node_access_records为每个node定义realm和gid及访问权
如果user与node的realm和gid吻合,定制的访问权就会生效

function hook_node_grants($account, $op) {
  if (user_access('access private content', $account)) {
    $grants['example'] = array(1);
  }
  $grants['example_author'] = array($account->uid);
  return $grants;
}
   
function hook_node_access_records($node) {
  // We only care about the node if it has been marked private. If not, it is
  // treated just like any other node and we completely ignore it.
  if ($node->private) {
    $grants = array();
    // Only published nodes should be viewable to all users. If we allow access
    // blindly here, then all users could view an unpublished node.
    if ($node->status) {
      $grants[] = array(
        'realm' => 'example',
        'gid' => 1,
        'grant_view' => 1,
        'grant_update' => 0,
        'grant_delete' => 0,
        'priority' => 0,
      );
    }
    // For the example_author array, the GID is equivalent to a UID, which
    // means there are many groups of just 1 user.
    // Note that an author can always view his or her nodes, even if they
    // have status unpublished.
    $grants[] = array(
      'realm' => 'example_author',
      'gid' => $node->uid,
      'grant_view' => 1,
      'grant_update' => 1,
      'grant_delete' => 1,
      'priority' => 0,
    );

    return $grants;
  }
}
   

hook_node_access_records在node_access_rebuild()时被激活,会直接写入数据表node_access,在下次rebuild之前不会再被调用。hook_node_grants在用户登录后被激活,直接与node_access数据进行匹配。

通俗说明,hook_node_access_records就是为node设置锁孔,hook_node_grants是使用user手上的钥匙配对node锁孔的过程。node_access表即是存储锁孔的表,access rebuild时会把node_access表清空,再以hook_node_access_records作为工厂来生成锁孔。

直接写入权限声明

$record = array(
  'nid' => 0,
  'gid' => 888,
  'realm' => 'example_realm',
  'grant_view' => 1,
  'grant_update' => 0,
  'grant_delete' => 0,
);
drupal_write_record('node_access', $record);
   
  • gid的意义由module决定,它可以是role id,也可以是user id。

  • 权限声明可以用hook_node_grants()实现,但需要使用node_access_rebuild()才会入库

  • 如果需要马上写入node_access,可用node_access_write_grants()

if ($op == 'view') {
  $grants['example_realm'] = array(888);
}
   

让DB Query识别权限

$query = db_select('node', 'n')->addTag('node_access');

hook_node_grants与hook_node_access的不同之处

hook_node_grants不只是在node full view生效,在views list与menu上也同样生效,没有权限的node不会出现在node和menu中。
hook_node_access只作用于menu,是node_access的扩展功能。由于node的access callback指向node_access,所以hook_node_access直接影响MENU的可见性。
所以如果想彻底让NODE不可见,可以使用hook_node_grants与hook_node_access_records,否则可以使用hook_node_access

hook_node_grants 适合实现NODE VIEW权限
hook_node_access 适合实现NODE CREATE, UPDATE, DELETE

menu access

/* Implements hook_menu_alter(). */
function mymodule_menu_alter(&$items) {
    $items['node/%/edit']['access callback'] = 'mymodule_access_callback';
    $items['training/course/%/files-download']['access arguments'] = array(2);
}
   

node_access_acquire_grants

如果通过程序更新了NODE,但又需要同时更新它的权限,需要执行node_access_acquire_grants($node);

views custom access

在module里实现hook_views_plugins

/* Implements hook_views_plugins() */
function mymodule_views_plugins() {
$plugins = array(    
'access' => array(      
'nwst' => array(        
'title' => t('Custom Access'),        
'help' => t('this is a custom access plugin'),        
'handler' => 'mymodule_access_plugin',        
'path' => drupal_get_path('module', 'mymodule'),    
  ),  
  ), 
 );  return $plugins;
}
   

创建一个程序mymodule_access_plugin.inc代码如下:

/** Access plugin that provides router item-based access control.
* @ingroup views_access_plugins
*/
class mymodule_access_plugin extends views_plugin_access {
    function access($account) {    
        // your code    return true;  
    }
}
   

需要在mymodule.info包含它:
files[] = mymodule_access_plugin.inc

参考:http://dominiquedecooman.com/...    

drupal    

来自  https://segmentfault.com/a/1190000006138361


drupal 7 hook_node_grants  hook_node_access_records  作用 示例


在 Drupal 7 中,hook_node_grantshook_node_access_records 是两个与节点访问控制相关的重要钩子。它们分别用于定义某用户可以访问哪些节点,以及某节点的访问权限记录。

hook_node_grants

hook_node_grants 钩子用于返回当前用户对节点的访问权限的集合。Drupal 使用这些集合来决定某用户是否可以访问某些节点。

作用:

  • 定义用户对不同内容类型和操作的权限。

  • 返回一个数组,其中包含影响用户节点访问权限的集合。

示例:

php
/**
 * Implements hook_node_grants().
 *
 * @param $account
 *   帐户对象,电子邮件,uid 等等。
 * @param $op
 *   操作,通常是 "view" / "update" / "delete"。
 *
 * @return array
 *   一个数组,键是 realm,值是 grant IDs 的数组。
 */
function mymodule_node_grants($account, $op) {
  // initialize an empty $grants array
  $grants = array();

  // Allow all authenticated users to view nodes in the 'example' realm.
  if ($account->uid > 0 && $op == 'view') {
    $grants['example'] = array(1);
  }

  // Example for more complex logic based on user roles.
  if (in_array('administrator', $account->roles)) {
    $grants['example'] = array(1, 2, 3); // admin gets more access ids.
  }

  return $grants;
}
Open in:

hook_node_access_records

hook_node_access_records 钩子生成节点的访问记录。返回的记录用于告知 Drupal 某节点的访问控制列表(ACL)。

作用:

  • 返回一个数组,其中定义了对特定节点的访问权限。

  • 这些记录告诉 Drupal 某用户是否可以访问某节点。

示例:

php
/**
 * Implements hook_node_access_records().
 *
 * @param $node
 *   节点对象
 *
 * @return array
 *   一个数组,定义节点的访问权限。
 */
function mymodule_node_access_records($node) {
  // Initialize an empty $grants array
  $grants = array();

  // Only create access records for 'article' content type
  if ($node->type == 'article') {
    // Allow public access for view operations
    $grants[] = array(
      'realm' => 'example',
      'gid' => 1,
      'grant_view' => 1,
      'grant_update' => 0,
      'grant_delete' => 0,
    );
    // Specific grant for update operations
    $grants[] = array(
      'realm' => 'example',
      'gid' => 2,
      'grant_view' => 1,
      'grant_update' => 1,
      'grant_delete' => 0,
    );
  }

  return $grants;
}
Open in:

工作流程

  1. 当用户尝试访问节点时,Drupal 首先调用 hook_node_grants 来确定用户的访问权限。

  2. 之后,Drupal 会调用 hook_node_access_records 来获取该节点的访问记录,并依据这些记录判断用户能否按其权限完成对应的操作。

通过这两个钩子,Drupal 能够灵活地控制用户对不同节点的访问权限。




drupal 7 hook_node_grants  hook_node_access_records  作用 示例

在Drupal 7中,hook_node_grants()的作用是为节点访问权限系统提供一组权限“授予”(grants),这些权限可以基于用户的角色、组成员资格或其他自定义条件。这些“授予”随后被用于决定用户是否有权访问特定的节点集合。这个hook主要用于模块开发,以便它们能够向节点访问控制系统添加自己的访问规则,而无需直接修改每个节点的访问权限。

通过实现hook_node_grants(), 模块可以基于全局条件(不针对单个节点)来确定哪些用户或用户组应该有权限访问哪些类型的节点。这些“授予”结果会被node_access()系统使用,作为计算节点访问权限的一部分逻辑。

下面是一个简化的示例,展示如何实现hook_node_grants()来为具有特定角色的用户提供访问权限:

Php    
1/**
2 * Implements hook_node_grants().
3 */
4function mymodule_node_grants($account) {
5  $grants = array();
6
7  // 检查用户是否具有"编辑员"角色(这里假设角色ID为4)。
8  if (user_has_role($account, 'editor')) {
9    // 如果是,向$grants数组添加一个标识,表示他们有特定的访问权限。
10    $grants['my_module_editor_access'] = TRUE;
11  }
12
13  return $grants;
14}

在这个例子中,我们创建了一个名为my_module_editor_access的权限“授予”。如果用户具有"编辑员"角色,他们就会获得这个“授予”。之后,在hook_node_access_records()或直接在数据库的node_access表中,可以通过这个“授予”来指派节点访问权限,允许具有此“授予”的用户访问相应的节点。

请注意,为了使这个机制完全生效,你可能还需要实现hook_node_access_records()来定义这些“授予”如何映射到具体的节点访问记录上,以及可能需要在管理界面或模块安装时设置相关的访问控制列表(ACL)条目。

总结来说,hook_node_grants()是Drupal权限系统中的一个重要环节,它使得开发者能够灵活地基于用户属性或角色来批量分配节点访问权限。


在Drupal 7中,hook_node_access_records()的作用是为特定的节点或节点类型定义访问控制的详细记录,这些记录将存储在node_access表中,用于高效地查询和判断用户是否有权访问给定的节点。这个hook允许模块根据节点的ID(nid)、节点类型、或是其他特定条件来设置访问控制规则,从而实现细粒度的权限管理。

通过实现hook_node_access_records(),模块可以插入或更新node_access表中的行,为每个节点或节点类型定义访问控制条目。这些条目通常包括一个权限标识符(由hook_node_grants()提供的“授予”),以及与之关联的权限级别(如允许或拒绝访问)。这些记录用于构建一个访问控制列表(ACL),当用户尝试访问一个节点时,Drupal会参考这些记录来决定是否允许访问。

下面是一个简化的示例,说明如何使用hook_node_access_records()来设置节点访问权限:

Php    
1/**
2 * Implements hook_node_access_records().
3 */
4function mymodule_node_access_records($node) {
5  $records = array();
6
7  // 假设我们想要为特定节点类型设置权限
8  if ($node->type == 'private_document') {
9    // 获取所有具有'my_module_private_reader'权限授予的用户
10    $granted_users = mymodule_get_users_with_grant('my_module_private_reader');
11
12    foreach ($granted_users as $uid => $user) {
13      // 为每个有权限的用户创建一条访问记录
14      $record = array(
15        'nid' => $node->nid,
16        'gid' => 0, // 使用用户ID作为grant ID,如果使用组,则使用组的GID
17        'realm' => 'my_module', // 自定义权限领域,用于区分不同模块设置的权限
18        'grant_view' => 1, // 允许查看
19        'grant_update' => 0, // 不允许编辑
20        'grant_delete' => 0, // 不允许删除
21      );
22
23      // 如果节点已经存在相应的访问记录,则更新它;否则,插入新记录
24      db_merge('node_access')
25        ->key(array('nid' => $record['nid'], 'gid' => $record['gid'], 'realm' => $record['realm']))
26        ->fields($record)
27        ->execute();
28    }
29  }
30
31  return $records; // 实际操作中这里可能不需要返回值,取决于你的实现方式
32}


在这个示例中,我们为类型为'private_document'的节点设置了访问控制记录,只允许具有'my_module_private_reader'权限标识的用户查看这些节点。通过查询或计算出具有该权限的用户列表,然后为每个用户和节点创建或更新node_access表中的记录,我们可以精确控制节点的访问权限。

需要注意的是,虽然示例代码中包含了一个返回$records的语句,实际上在很多情况下,直接操作数据库(如使用db_merge)来插入或更新记录更为常见,因此返回值可能并非必需。重要的是理解这个hook是用来动态生成或修改节点访问控制记录的关键所在。




普通分类: