Blocks, by default, are rendered for all users. The default access method can be overridden. This allows a block to only be displayed to authenticated users or based on a specific permission:
/**
* {@inheritdoc}
*/
protected function blockAccess(AccountInterface $account) {
$route_name = $this->routeMatch->getRouteName();
if ($account->isAnonymous() && !in_array($route_name,
array('user.login', 'user.logout'))) {
return AccessResult::allowed()
->addCacheContexts(['route.name',
'user.roles:anonymous']);
}
return AccessResult::forbidden();
}
The preceding code is taken from the user_login_block. It allows access to the block if the user is logged out and is not in the login or logout page. The access is cached based on the current route name and the user's current role being anonymous. If these are not passed, the access returned is forbidden and the block is not built.
Other modules can implement hook_block_access to override the access of a block:
/**
* Implements hook_block_access().
*/
function mymodule_block_access(\Drupal\block\Entity\Block $block, $operation, \Drupal\Core\Session\AccountInterface $account) {
// Example code that would prevent displaying the Copyright' block in
// a region different than the footer.
if ($operation == 'view' && $block->getPluginId() == 'copyright') {
return \Drupal\Core\Access\AccessResult::forbiddenIf($block->getRegion() != 'footer');
}
// No opinion.
return \Drupal\Core\Access\AccessResult::neutral();
}
A module implementing the preceding hook will deny access to our Copyright block if it is not placed in the footer region.