Example: Node Access

  1. drupal
    1. 8
    2. 6
    3. 7

Demonstrates node access.

This is an example demonstrating how to grant or deny access to nodes using the Drupal core API node access system.

This module will add a 'private' flag for each node, which the node's author can manage. Nodes marked private can only be viewed, edited, or deleted by the author. However, not everything is as private as it seems on the internet, and so we need to implement some ways to allow other users to manage this 'private' content.

We will use the node grant system to specify which users are allowed to view, edit, or delete 'private' content. We will also allow a user named 'foobar' to have edit privileges on private content as well.

In addition, we will provide a page which will show some minimal instructions, and statistics on private nodes on the site.

We use NodeAPI hooks to put a single marker on a node, called 'private'. The marker is implemented by a database table which has one row per node simply indicating that the node is private. If the "private" marker is set, users other than the owner and privileged users are denied access.

Standard permissions are defined which allow users with 'access any private content' or 'edit any private content' to override the 'private' node access restrictions.

A separate access realm grants privileges to each node's author, so that they can always view, edit, and delete their own private nodes.

The only page provided by this module gives a rundown of how many nodes are marked private, and how many of those are accessible to the current user. This demonstrates the use of the 'node_access' tag in node queries, preventing disclosure of information which should not be shown to users who don't have the proper permissions.

Most relevant functions:

Drupal's node access system has three layers.

  • Overall override permissions. User 1 and any user with 'bypass node access' permission are automatically granted access.
  • hook_node_access() gives each module the opportunity to approve or deny access. Any module that returns NODE_ACCESS_DENY from hook_node_access() will result in denial of access. If no module denies access and one or more modules allow access, then access is granted. hook_node_access() was introduced in Drupal 7.
  • If no resolution has yet been reached, then the node_access table is used along with hook_node_grants(). (Drupal updates the node_access table when nodes are saved, by calling hook_node_access_records().)

Note that the hook_node_grants()/hook_node_access_records() layer is a first-grant-wins system, which means a module using it can't deny access to a node. Contributed modules have been developed to overcome this shortcoming, with their own APIs, such as ACL. ACL, in fact, has emerged as the more-or-less standard solution for fine-grained access control, and you really should be reading up on it. Many modules use it, and if your module implements another node access system, there could be chaos.

A list of the many node access modules (and differing APIs) is here: Overview of Node Access Modules. Note that this is Drupal 6 documentation, linked here so the reader can understand the historical reasons for using contributed node access modules such as ACL.

See also





Functions & methods

node_access_example_form_alterImplements hook_form_alter().
node_access_example_menuImplements hook_menu().
node_access_example_node_accessImplements hook_node_access().
node_access_example_node_access_recordsImplements hook_node_access_records().
node_access_example_node_deleteImplements hook_node_delete().
node_access_example_node_grantsImplements hook_node_grants().
node_access_example_node_insertImplements hook_node_insert().
node_access_example_node_loadImplements hook_node_load().
node_access_example_node_updateImplements hook_node_update().
node_access_example_permissionImplements hook_permission().
node_access_example_private_node_listingOur hook_menu() page callback function.


NODE_ACCESS_EXAMPLE_GRANT_ALLHere we define a constant for our node access grant ID, for the node_access_example_view and node_access_example_edit realms. This ID could be any integer, but here we choose 23, because it is this author's favorite number.

examples/node_access_example/node_access_example.module, line 8