为某些节点发出403

Kev*_*vin 4 drupal drupal-6

你如何为某些节点发出403?我尝试使用drupal_access_denied.当我收到Access Denied消息时,看门狗充满了:

无法修改标头信息 - 已发送的标头

这是正常的吗?我没有使用drupal_access_denied吗?

小智 6

使用建议hook_nodeapi()还为时已晚.

如果你使用它$op = load,你可能会耗尽你的记忆,因为Drupal已经承诺了加载节点时所做的所有正常事情(包括加载多次).

如果您使用$op = view,如果您执行以下操作,则可以"伪造"它:

function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    case 'view':
      drupal_access_denied();
      exit();
      break;
  }
}
Run Code Online (Sandbox Code Playgroud)

但它不是真正的403:除了Watchdog之外它不会被报告,并且所有正常的东西仍然会加载并渲染,就像节点在那里一样.

为了方便起见,您可以使用hook_init():

function mymodule_init() {
  $nodes_403 = array(42, 69, 187);
  if (arg(0) == 'node' && in_array(arg(1), $nodes_403))
    drupal_access_denied();
    exit();
  }
}
Run Code Online (Sandbox Code Playgroud)

但这不必要地绕过了Drupal的内置权限系统.相反,您希望利用Drupal的节点访问权限系统来拒绝对节点的访问.

如果您在模块中定义了自己的内容类型,则可以使用hook_access():

function mymodule_access($op, $node, $account) {
  $nodes_403 = array(42, 69, 187);

  if (in_array($node->nid, $nodes_403)) {
    return FALSE;
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您没有定义自己的自定义内容类型,hook_access()则永远不会调用.因此,您需要access callback使用自己的路径覆盖节点路径:

function mymodule_menu_alter(&$items) {
  $items['node/%node']['access callback'] = 'mymodule_access';
}

function mymodule_access($op, $node, $account = NULL) {
  $nodes_403 = array(42, 69, 187);

  if ($op == 'view' && in_array($node->nid, $nodes_403)) {
    return FALSE;
  }

  return node_access($op, $node, $account);
}
Run Code Online (Sandbox Code Playgroud)

由于hook_menu_alter()实现,请确保在执行上述操作后重建菜单系统.