ACL - Access Control List
The Access Control List (ACL) Module allows you to define authorization rules to access resources in your application.
Under the hood, the Modular ACL System provides an Interface integrated with Spatie's Laravel-permission package, which is used to handle the permissions and roles for the logged-in users in your application.
You can create roles
for your users, like admin
and marketing
. Create permissions
that represent the actions that your users can perform, like create
, edit
, delete
, and view
resources. And finally, you can assign permissions to roles, and assign roles to the users of the application.
In cases where you need granular control over user permissions, you can also assign permissions directly to users, and this will override the permissions that the user has through the roles.
The ACL System will require updates in two parts of your application:
1 - The sidebar navigation menu
(and other links to resources in your application) to show or hide the menu items based on the permissions of the logged user.
2 - The Laravel routes
, to allow or deny access to the routes based on the permissions of the logged user.
In this manner, the ACL operates on two different layers; the first one disables the links to protected resources in your application's interface. The second one, denies access to the routes of the protected resources, even if the user tries to directly access the route in the browser.
Disabling Resources in the Sidebar Navigation Menu
The Sidebar Navigation Menu is generated automatically by the resources/js/Components/AppMenu.vue
component, which is configured in the resources/js/Configs/menu.js
file.
A clean install of Modular will set the resources/js/Configs/menu.js
file with the following content:
import { ZiggyVue } from "/vendor/tightenco/ziggy/dist/vue.m";
export default {
// main navigation - side menu
items: [
{
label: "Dashboard",
permission: "Main Menu: Dashboard",
icon: "ri-dashboard-line",
link: route("dashboard.index"),
},
{
label: "Access Control List",
permission: "Main Menu: Access Control List",
children: [
{
label: "Users",
permission: "Main Menu: Access Control List: Users - List",
icon: "ri-user-line",
link: route("user.index"),
},
{
label: "Permissions",
permission: "Main Menu: Access Control List: Permissions - List",
icon: "ri-shield-keyhole-line",
link: route("aclPermission.index"),
},
{
label: "Roles",
permission: "Main Menu: Access Control List: Roles - List",
icon: "ri-account-box-line",
link: route("aclRole.index"),
},
],
},
],
};
This is translated by the AppMenu.vue
component to the following sidebar menu:
The permission
property of each menu item is the permission that the user must have to see the menu item in the sidebar menu.
You should always maintain a 1:1 relationship between the menu items and the ACL permissions created for your application (listed in alphabetical order):
Now you can create a new role
and assign the permissions to it. In this example, the admin
role will have access to the app Dashboard but will not manage users
resources.
The last step is to assign the admin
role to a user. Now, the user will be able to access the Dashboard, but will not see the Users
menu item in the sidebar menu.
Extending ACL restrictions to other links and buttons
During the development lifecycle of your application, you'll likely need to manage links and buttons that are outside the AppMenu.vue
. To apply this ACL feature to these links and buttons, you can utilize the can()
method from the resources/js/Composables/useAuthCan.js
file:
<template>
<button v-if="can('Main Menu: Access Control List: Users - Create')">
Add User
</button>
</template>
<script setup>
import useAuthCan from "@/Composables/useAuthCan";
const { can } = useAuthCan();
</script>
Protecting Routes
Following the instructions from the previous section will disable the links to the protected resources in the sidebar menu and other parts (buttons and links) of your application. However, users can still access the routes directly in the browser.
To ensure the ACL Module protects the routes of your application, you must apply the ACL protection method can()
to your routes:
<?php
use Illuminate\Support\Facades\Route;
Route::get('user', [
'uses' => 'UserController@index',
])
->can('Main Menu: Access Control List: Users - List')
->name('user.index');
This will ensure that the user will be able to access the route only if they have the permission Main Menu: Access Control List: Users - List
.
You can create your own naming system for permission names if you prefer. For example, use user.index
instead of the longer Main Menu: Access Control List: Users - List.
Roles, Permissions, and Precedence
If you create a user and assign a role to them, the user will have all the permissions that the role has. However, if you assign a permission directly to the user, this will override the permissions that the user has through the role. So keep in mind that: permissions assigned directly to the user will always override the permissions that the user has through the roles.