【问题标题】:Issue a 403 for certain nodes为某些节点发出 403
【发布时间】:2010-09-16 19:46:32
【问题描述】:

如何为某些节点发出 403?我尝试使用 drupal_access_denied。当我收到拒绝访问消息时,看门狗充满了:

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

这正常吗?我没有使用 drupal_access_denied 对吗?

【问题讨论】:

  • 你在哪里发出拒绝?在主题上,为时已晚。但是,您可以毫无问题地在 hook_nodeapi 中发出它。
  • 加载操作中的 hook_nodeapi 是我拥有它的地方。是否有可能登录雪橇受到干扰?

标签: drupal drupal-6


【解决方案1】:

使用建议的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;
  }
}

但这不是真正的 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();
  }
}

但这会不必要地绕过 Drupal 的内置权限系统。相反,您想利用 Drupal 的 node access rights 系统来拒绝对节点的访问。

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

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

  if (in_array($node->nid, $nodes_403)) {
    return FALSE;
  }
}

但如果您不定义自己的自定义内容类型,则永远不会调用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);
}

由于hook_menu_alter() 的实现,请确保在实现上述操作后重建您的菜单系统。

【讨论】:

  • 我能够通过执行 drupal_access_denied(); 来消除“标题”错误。休息;在每次检查时——但我也会看看你的方法。希望这种解释在 API 中。 api.drupal.org/api/function/drupal_access_denied/6
  • @Kevin:众所周知,节点访问 API 的文档记录很糟糕,当它开始设计得很糟糕时,这无济于事(为什么我在定义自己的自定义内容类型时只能使用 hook_access(),而不是在所有节点上?或者就此而言,在 any 页面上)。 Drupal 7 清理了 API,因此希望文档得到一些喜爱。
  • 是的 - 我注意到这破坏了用户 0 的某些 cron 功能。我重构了你的方法。另外,我是不是疯了,或者 nodeapi 视图案例没有像你期望的那样工作?
  • @Kevin,hook_nodeapi() 中的view 操作是对hook_view() 的非节点模块补充:主要用于在$node->content 中添加额外的字段,在很晚才被调用节点构建过程。当它被调用时,您已经承诺显示该节点。
  • 明白了。用了你的方法。多么奇怪的怪癖。
猜你喜欢
  • 2015-12-31
  • 2011-09-26
  • 1970-01-01
  • 2016-11-23
  • 2019-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多