Node access rights in Drupal 10
Same name and namespace in other branches
- 8 core/modules/node/node.module \node_access
- 4 modules/node.module \node_access
- 5 modules/node/node.module \node_access
- 6 modules/node/node.module \node_access
- 7 modules/node/node.module \node_access
- 9 core/modules/node/node.module \node_access
The node access system determines who can do what to which nodes.
In determining access rights for an existing node, \Drupal\node\NodeAccessControlHandler first checks whether the user has the "bypass node access" permission. Such users have unrestricted access to all nodes. user 1 will always pass this check.
Next, all implementations of hook_ENTITY_TYPE_access() for node will be called. Each implementation may explicitly allow, explicitly forbid, or ignore the access request. If at least one module says to forbid the request, it will be rejected. If no modules deny the request and at least one says to allow it, the request will be permitted.
If all modules ignore the access request, then the node_access table is used to determine access. All node access modules are queried using hook_node_grants() to assemble a list of "grant IDs" for the user. This list is compared against the table. If any row contains the node ID in question (or 0, which stands for "all nodes"), one of the grant IDs returned, and a value of TRUE for the operation in question, then access is granted. Note that this table is a list of grants; any matching row is sufficient to grant access to the node.
In node listings (lists of nodes generated from a select query, such as the default home page at path 'node', an RSS feed, a recent content block, etc.), the process above is followed except that hook_ENTITY_TYPE_access() is not called on each node for performance reasons and for proper functioning of the pager system. When adding a node listing to your module, be sure to use an entity query, which will add a tag of "node_access". This will allow modules dealing with node access to ensure only nodes to which the user has access are retrieved, through the use of hook_query_TAG_alter(). See the Entity API topic for more information on entity queries. Tagging a query with "node_access" does not check the published/unpublished status of nodes, so the base query is responsible for ensuring that unpublished nodes are not displayed to inappropriate users.
Note: Even a single module returning an AccessResultInterface object from hook_ENTITY_TYPE_access() whose isForbidden() method equals TRUE will block access to the node. Therefore, implementers should take care to not deny access unless they really intend to. Unless a module wishes to actively forbid access it should return an AccessResultInterface object whose isAllowed() nor isForbidden() methods return TRUE, to allow other modules or the node_access table to control access.
Note also that access to create nodes is handled by hook_ENTITY_TYPE_create_access().
To see how to write a node access module of your own, see node_access_example.module.
See also
\Drupal\node\NodeAccessControlHandler
File
- core/
modules/ node/ node.module, line 768 - The core module that allows content to be submitted to the site.
Functions
Name | Location | Description |
---|---|---|
hook_node_access_records |
core/ |
Set permissions for a node to be written to the database. |
hook_node_access_records_alter |
core/ |
Alter permissions for a node before it is written to the database. |
hook_node_grants |
core/ |
Inform the node access system what permissions the user has. |
hook_node_grants_alter |
core/ |
Alter user access rules when trying to view, edit or delete a node. |
node_access_grants |
core/ |
Fetches an array of permission IDs granted to the given user ID. |
node_access_needs_rebuild |
core/ |
Toggles or reads the value of a flag for rebuilding the node access grants. |
node_access_rebuild |
core/ |
Rebuilds the node access database. |
node_access_view_all_nodes |
core/ |
Determines whether the user has a global viewing grant for all nodes. |
node_node_access |
core/ |
Implements hook_ENTITY_TYPE_access(). |
node_query_node_access_alter |
core/ |
Implements hook_query_TAG_alter(). |
_node_access_rebuild_batch_finished |
core/ |
Implements callback_batch_finished(). |
_node_access_rebuild_batch_operation |
core/ |
Implements callback_batch_operation(). |
Classes
Name | Location | Description |
---|---|---|
NodeAccessControlHandler |
core/ |
Defines the access control handler for the node entity type. |
NodeAccessGrantsCacheContext |
core/ |
Defines the node access view cache context service. |
NodeGrantDatabaseStorage |
core/ |
Defines a storage handler class that handles the node grants system. |
NodePreviewAccessCheck |
core/ |
Determines access to node previews. |
Interfaces
Name | Location | Description |
---|---|---|
NodeAccessControlHandlerInterface |
core/ |
Node specific entity access control methods. |
NodeGrantDatabaseStorageInterface |
core/ |
Provides an interface for node access grant storage. |