I'm using Drupal 7 and I created a new content type called "eBook," and I created a new role called "MonthlySubscriber." My intention is to allow only users with the "MonthlySubscriber" to view the "eBook" nodes. When I looked at the permission settings for a role, I saw the checkboxes that allows to create, edit and delete nodes of that content type, but there are no checkboxes for viewing nodes.

How do I limit the users who can view "eBook" nodes to just the users with the "MonthlySubscriber" role?

8 Answers 8


You need to install Content Access module to add this access control.

This module allows you to manage permissions for content types by role and author. It allows you to specifiy custom view, edit and delete permissions for each content type.


For drupal 7, try using hook_node_access():

 * Implements hook_node_access().
function YOURMODULE_node_access($node, $op, $account) {
  if (
    $node->type == 'ebook' &&
    $op == 'view' &&
    !in_array('MonthlySubscriber', $account->roles)
  ) { return NODE_ACCESS_DENY; }
  • 2
    Please avoid code-only answers. They serve no learning purpose. At least explain in a sentence or three how exactly this particular code is an answer? How does it work? why it works? The kind of description that will help others to write similar code in similar situation ,instead of asking again and again.
    – Mołot
    Commented Sep 17, 2015 at 6:14
  • This should be the correct answer.
    – GrafiCode
    Commented Jan 16, 2018 at 14:46
  • Don't forget to clear your cache after any code changes here. Commented Jan 21, 2021 at 17:38

Here is a simple way protect node pages (node/NID) from unprivileged users.

 * Implements hook_menu_alter().
function mymodule_menu_alter(&$items) {
  $items['node/%node']['access callback'] = 'mymodule_check_node_access';

 * Determines whether the current user may perform the operation on the node.
function mymodule_check_node_access($op, $node) {
  if ($node->type == 'protected_type' && !user_access('administer site configuration')) {
    return FALSE;
  return node_access($op, $node);
  • 2
    Note that using hook_node_access will not work with anything that "lists" nodes, like a View. So you may restrict view access in hook_node_access, but a View or custom node query may still show that node to the user. hook_node_access is more useful for editorial control, for controlling create/update/delete operations
    – Brian
    Commented Jul 18, 2014 at 12:47
  • Your code doesn't work for me, but you pointed me in the right direction. I found working code on the hook_node_access documentation api.drupal.org/api/drupal/modules%21node%21node.api.php/…
    – Camilo
    Commented Jun 11, 2015 at 14:06
  • This is a bad example because it use mymodule_node_access as custom function while Drupal provides a hook_node_access hook. This can become confusing.
    – batigolix
    Commented Jun 1, 2017 at 12:01
  • @batigolix, as stated in the answer it is a way to protect node pages not nodes.
    – ya.teck
    Commented Jun 2, 2017 at 3:43

Content Access didn't work for my Drupal 7 install, so I used Node View Permissions instead.


For drupal 7, try this one: Access by Term

Provides very flexible, hierarchical node access control (content access control), for D7.


I perfer using the Node View Permissions module. It's simpler than the Content Access module.

As in D6, it adds "View any content" and "View own content" permissions to any content type that you choose.

enter image description here

Steps to follow:

  1. After installing and enabling, go to /admin/config/content/node-view-permissions and select which content types that you want to limit access to.
  2. Then, go to /admin/people/permissions#module-node_view_permissions and select the roles that you want to be able to view the content. Save permissions.


  • for drupal 8 "Node View Permissions " is not working Commented Sep 7, 2017 at 11:32
  • @KarthikeyanManivasagam How so? Commented Sep 8, 2017 at 5:39
  • We used this module in one of our project where we need to provide content view access based on role and content type, but its not working at all. it behaves remains the same like without using this module. Commented Sep 8, 2017 at 11:36

The hook_menu_alter solution posted above by ya.teck does work, but conflicts with the standard hook_node_access in its function name. the hook_menu_alter is not required in this case, and so the answer posted by Denis above is in my opinion more accurate and the proper way. Altering the menu_item as is done is the first referenced example could be clobbered by another module further down the pipe.


I used a code snippet found in the D7 api documentation for the hook_node_access hook.

This code will grant access to view "ebook" content to users that have the "view ebook" permission.

You need a new permission to control access by implementing hook_permission().

 * Implements hook_permission().
function mymodule_permission() {
  return array(
    'view ebook' => array(
      'title' => t('View Ebook'),
      'description' => t('View Ebook nodes.'),

By implementing hook_node_access() Drupal can grant or deny the access to the node.

 * Implements hook_node_access().
function mymodule_node_access($node, $op, $account) {

  // Checks for an ebook node in view mode.
  if (is_object($node) && $node->type === 'ebook' && $op === 'view') {

    // Grants permission to view the node if the current user has an role
    // with the permission 'view ebook'.
    if (user_access('view ebook')) {
      return NODE_ACCESS_ALLOW;

    // Otherwise disallows access to view the node.
    return NODE_ACCESS_DENY;
  // For all other nodes and other view modes, don't affect the access.

Other permissions (edit, delete, etc) can be dealt with via the normal Drupal permissions.

Optionally you can remove the content from the admin overview by implementing hook_query_TAG_NAME_alter.

 * Implements hook_query_TAG_NAME_alter().
function mymodule_query_node_admin_filter_alter(QueryAlterableInterface $query) {
  if (!user_access('view ebook')) {
  $query->condition('n.type', 'ebook', '!=');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.