Custom node access control not working with access filter?
Lists like views will not be passed through hook_node_access(), as this would create too much overhead. Views does a query on the database to get the results. hook_node_access() is run in PHP, so these won't work (easily/well/efficently) together.

To deal with lists, you will need to create a grant system, using hook_node_access_records() and hook_node_grants(). This system writes to the {node_access} table in the database, and when a list is created, the database query is cross-referenced with that table.

hook_node_access_records() is called when a node is saved. Modules that implement this hook can set up various states by which the node is allowed to be accessed.

hook_node_grants() is then called when the node is viewed/updated/deleted. A set of potential grants is created based on the current environment, and these are compared with the states created in hook_node_access_records(). If there is a match, access is provided.

In your case, hook_node_access_records() should create a state whereby if the node has the field field_content_protect, then a state should be created upon which view access can be either granted or denied in hook_node_grants(). Example:

function MODULE_node_access_records(\Drupal\node\NodeInterface $node) {
  if ($node-&gt;hasField('field_content_protect')) {
    $grants = [];

    $grants[] = [
      'realm' =&gt; 'MODULE_protect_content',
      // This is set to 1. In hook_node_grants(), 
      // A value will be created based on the user's
      // logged in state, and compared to this value.
      'gid' =&gt; 1,
      'grant_view' =&gt; 1,
      'grant_update' =&gt; 0,
      'grant_delete' =&gt; 0,
    ];

    return $grants;
  }
}


The above sets up a state, whereby if a grant is created for the realm MODULE_protect_content that has a value of 1, the user should be granted view access. The next thing is to implement hook_node_grants() and create a grant based on the current user's status.

function MODULE_node_grants() {
  $current_user = \Drupal::currentUser();
  $grants = [];

  // This will set a value of 0 (zero) or 1 (one)
  // for the realm MODULE_protect_content. If the
  // value is 1 (authenticated user) the user will
  // be provided view access to the node. Note 
  // that an array of values must be passed for
  // realms.
  $status = (int) $current_user-&gt;isAuthenticated();
  $grants['MODULE_protect_content'] = [$status];

  return $grants.
}


For the above code, a grant is created based on the logged in status of the current user. If they are logged in, $status will equal 1, which is compared with the state provided in hook_node_access_records() providing access to the user.

You could actually alter the above hook_node_grants() to only return a grant if the user is logged in. I'm not sure which one would be more efficient. I suspect the code below may be:

function MODULE_node_grants() {
  $current_user = \Drupal::currentUser();

  if ($status = (int) $current_user-&gt;isAuthenticated()) {
    $grants = [];
    // This will set a value of 1 (one)
    // for the realm MODULE_protect_content, which
    // matches the state created in
    // hook_node_access_records(). Note that
    // an array of values must be passed for 
    // realms.
    $grants['MODULE_protect_content'] = [$status];

    return $grants.
  }
}