Now that we saw how the access system works in Drupal 8 at a basic level, and how we can define permissions and check user credentials, it's time to talk about routes.
As we've seen from the very first time we wrote code in this book, routes are the entry points into your application. Also, as a developer, it is one of the main things you'll be dealing with, and controlling who exactly can access these routes falls under the purview of the access system.
There are a number of ways we can ensure that routes are only accessible to the right users, so let's see what these are.
The simplest way is by checking for a permission. We've actually done that in Chapter 2, Creating Your First module, when we defined our hello_world.hello route:
hello_world.hello:
path: '/hello'
defaults:
_controller: '\Drupal\hello_world\Controller\HelloWorldController::helloWorld'
_title: 'Our first route'
requirements:
_permission: 'access content'
The requirements key in a route definition contains all the data that the request trying to reach this route must have. This can contain mostly access-like information, and also things such as the request format.
The requirement in the preceding example is _permission (all these options typically start with an underscore).It is used to specify that the user accessing this route needs to have that permission, similar to how we checked whether a user has it earlier:
$account->hasPermission($permission).
The access content permission is something defined by Drupal core and is basically the one you'd use when the restrictions are very lax, meaning that all users should be able to access the resource because, by default, this permission is also present on the Anonymous user role.
Speaking of lax restrictions, there is one option that is even more open, fully open:
_access: "TRUE"
This essentially opens up the route to basically everybody under any circumstance--not something you'll probably use often, but it's very handy in some cases.
Returning to permissions, we can also include multiple permissions in this requirement. For example, to check whether a user has either of two permissions, we separate them by a comma:
_permission: "my custom permission,administer site configuration"
For checking whether the user has all the given permissions, we separate them by a plus (+) sign:
_permission: "my custom permission+my other permission"
So, we can already see quite some flexibility. The administer site configuration is another staple permission from Drupal core, which we can use to ensure that the user is an administrator; it is typically a sensitive permission given only to these users.
Next, we also have a requirement by which we can check whether the user has a given role. In a similar manner, we can include multiple roles to check, depending on whether we want to do AND or OR checking:
_role: "administrator" _role: "editor,administrator" _role: "editor+administrator"
This approach is not as flexible as using permissions and is a little "hardcody". By this I mean that you are hardcoding an access rule based on site configuration (as roles are configuration entities). So, if that configuration is removed, you may have broken code. Permissions, on the other hand, are also code, as they are defined in a module (or Drupal core). However, the option is there if you need it.
The next type of requirement we should be covering here is _entity_access. However, understanding this requires us to first know a bit about entity level access, so we will skip it now; we'll definitely come back to it later in the chapter. Instead, we will talk about the mother of all route access approaches--the custom one.