Authorization happens once a user has been identified through authentication. It is the process of determining what actions a user is allowed to do within your site.
Shield provides a flexible role-based access control (RBAC) that allows users to belong to multiple groups at once. Groups can be thought of as traditional roles (admin, moderator, user, etc), but can also group people together around features, like Beta feature access, or used to provide discrete groups of users within a forum, etc.
Groups are defined within the Shield\Config\AuthGroups config class.
public array $groups = [
'superadmin' => [
'title' => 'Super Admin',
'description' => 'Optional description of the group.',
],
];The key of the $groups array is the common term of the group. This is what you would call when referencing the
group elsewhere, like checking if $user->inGroup('superadmin'). By default, the following groups are available:
superadmin, admin, developer, user, and beta.
When a user is first registered on the site, they are assigned to a default user group. This group is defined in
Config\AuthGroups::$defaultGroup, and must match the name of one of the defined groups.
public string $defaultGroup = 'user';All permissions must be added to the AuthGroups config file, also. A permission is simply a string consisting of
a scope and action, like users.create. The scope would be users and the action would be create. A scope can
have sub-scopes, as in forum.posts.delete, where the scope is forum, the sub-scope is posts, and the action
associated with this permission is delete. Each permission can have a description for display within UIs if needed.
public array $permissions = [
'admin.access' => 'Can access the sites admin area',
'admin.settings' => 'Can access the main site settings',
'users.manage-admins' => 'Can manage other admins',
'users.create' => 'Can create new non-admin users',
'users.edit' => 'Can edit existing non-admin users',
'users.delete' => 'Can delete existing non-admin users',
'beta.access' => 'Can access beta-level features',
'forum.posts.create' => 'Can create posts in the forum',
'forum.posts.edit' => 'Can edit posts in the forum',
'forum.posts.delete' => 'Can delete posts in the forum',
];In order to grant any permissions to a group, they must have the permission assigned to the group, within the AuthGroups
config file, under the $matrix property.
!!! note
This defines **group-level permissons**.
The matrix is an associative array with the group name as the key, and an array of permissions that should be applied to that group.
public array $matrix = [
'admin' => [
'admin.access',
'users.create', 'users.edit', 'users.delete',
'beta.access',
'forum.posts.create', 'forum.posts.edit', 'forum.posts.delete',
],
];You can use a wildcard within a scope or sub-scope to allow all actions within that scope or sub-scope, by using a * in place of the action.
public array $matrix = [
'superadmin' => ['admin.*', 'users.*', 'beta.*', 'forum.posts.*'],
];The Authorizable trait on the User entity provides the following methods to authorize your users.
Allows you to check if a user is permitted to do a specific action or group of actions. The permission string(s) should be passed as the argument(s). Returns
boolean true/false. Will check the user's direct permissions (user-level permissions) first, and then check against all of the user's groups
permissions (group-level permissions) to determine if they are allowed. When checking against group-level permissions, this includes evaluating
hierarchical wildcard permissions. For example, if a user's group has the permission forum.posts.*, a check for $user->can('forum.posts.create')
would return true.
if ($user->can('users.create')) {
//
}
// If multiple permissions are specified, true is returned if the user has any of them.
if ($user->can('users.create', 'users.edit')) {
//
}
// Example with hierarchical wildcard check.
// Assuming the $user is in a group with 'forum.posts.*' permission.
if ($user->can('forum.posts.create')) {
// This will return true
}When checking group-level permissions, Shield automatically creates a hierarchy check by examining parent permissions:
- For permission
forum.posts.create, it checks:forum.posts.create,forum.posts.*, andforum.* - For permission
admin.settings, it checks:admin.settingsandadmin.*
This allows for flexible permission management where broader permissions automatically grant access to more specific actions.
!!! warning
Be cautious when granting wildcard permissions, especially at high levels like `admin.*`, as they will grant access to any future permissions added under that scope.
Checks if the user is in one of the groups passed in. Returns boolean true/false.
if (! $user->inGroup('superadmin', 'admin')) {
//
}Checks to see if the user has the permission set directly on themselves. This disregards any groups they are part of.
if (! $user->hasPermission('users.create')) {
//
}!!! note
This method checks only **user-level permissions**, and does not check
group-level permissions. If you want to check if the user can do something,
use the `$user->can()` method instead.
You can restrict access to a route or route group through a Controller Filter.
One is provided for restricting via groups the user belongs to, the other
is for permission they need. The filters are automatically registered with the
system under the group and permission aliases, respectively.
You can set the filters within app/Config/Routes.php:
$routes->group('admin', ['filter' => 'group:admin,superadmin'], static function ($routes) {
$routes->group(
'',
['filter' => ['group:admin,superadmin', 'permission:users.manage']],
static function ($routes) {
$routes->resource('users');
}
);
});Note that the options (filter) passed to the outer group() are not merged with the inner group() options.
!!! note
If you set more than one filter to a route, you need to enable
[Multiple Filters](https://codeigniter.com/user_guide/incoming/routing.html#multiple-filters).
Permissions can be granted on a user level as well as on a group level. Any user-level permissions granted will override the group, so it's possible that a user can perform an action that their groups cannot.
Adds one or more user-level permissions to the user. If a permission doesn't exist, a CodeIgniter\Shield\Authorization\AuthorizationException
is thrown.
$user->addPermission('users.create', 'users.edit');Removes one or more user-level permissions from a user. If a permission doesn't exist, a CodeIgniter\Shield\Authorization\AuthorizationException
is thrown.
$user->removePermission('users.delete');Updates the user's user-level permissions to only include the permissions in the given list. Any existing permissions on that user not in this list will be removed.
$user->syncPermissions('admin.access', 'beta.access');Returns all user-level permissions this user has assigned directly to them.
$user->getPermissions();!!! note
This method does not return **group-level permissions**.
Adds one or more groups to a user. If a group doesn't exist, a CodeIgniter\Shield\Authorization\AuthorizationException
is thrown.
$user->addGroup('admin', 'beta');Removes one or more groups from a user. If a group doesn't exist, a CodeIgniter\Shield\Authorization\AuthorizationException
is thrown.
$user->removeGroup('admin', 'beta');Updates the user's groups to only include the groups in the given list. Any existing groups on that user not in this list will be removed.
$user->syncGroups('admin', 'beta');Returns all groups this user is a part of.
$user->getGroups();All users have an active flag. This is only used when the EmailActivation action, or a custom action used to activate a user, is enabled.
You can determine if a user has been activated with the isActivated() method.
if ($user->isActivated()) {
//
}!!! note
If no activator is specified in the `Auth` config file, `actions['register']` property, then this will always return `true`.
You can check if a user has not been activated yet via the isNotActivated() method.
if ($user->isNotActivated()) {
//
}Users are automatically activated within the EmailActivator action. They can be manually activated via the activate() method on the User entity.
$user->activate();Users can be manually deactivated via the deactivate() method on the User entity.
$user->deactivate();