In CodeIgniter 4, Roles and permission means that user can access application as well as features as he gets permission as per the role.
Let’s start to create a roles and permissions based access control system:
Step 1 – CodeIgniter 4 Project
Go to the official website of codeIgniter 4, and download zip and extract it in your xampp or wampp server.
Step 2 – Create Role and Permission Table
Run the following sql queries to create roles, permissions and users table:
CREATE TABLE `roles` (
`id` INT(11) AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`description` TEXT
);
CREATE TABLE `permissions` (
`id` INT(11) AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`description` TEXT
);
CREATE TABLE `role_permissions` (
`role_id` INT(11),
`permission_id` INT(11),
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`),
FOREIGN KEY (`permission_id`) REFERENCES `permissions`(`id`)
);
CREATE TABLE `users` (
`id` INT(11) AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NOT NULL,
`role_id` INT(11),
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`)
);
Step 3 – Create Models
Go to the app/models
directory and create models named user.php, role.php
and permission.php
:
Update code in RoleModel.php
model file:
<?php namespace App\Models;
use CodeIgniter\Model;
class RoleModel extends Model
{
protected $table = 'roles';
protected $primaryKey = 'id';
protected $allowedFields = ['name', 'description'];
}
Update code in PermissionModel.php
model file:
<?php namespace App\Models;
use CodeIgniter\Model;
class PermissionModel extends Model
{
protected $table = 'permissions';
protected $primaryKey = 'id';
protected $allowedFields = ['name', 'description'];
}
Update code in UserModel.php
model file:
<?php namespace App\Models;
use CodeIgniter\Model;
class UserModel extends Model
{
protected $table = 'users';
protected $primaryKey = 'id';
protected $allowedFields = ['username', 'password', 'role_id'];
public function getUserRole($userId)
{
return $this->where('id', $userId)->first()['role_id'];
}
}
Step 4 – Create Controllers
Go to app/controllers
directory, and create controllers to manage roles, permissions, and user access.
In RoleController.php
file:
<?php namespace App\Controllers;
use App\Models\RoleModel;
use App\Models\PermissionModel;
class RoleController extends BaseController
{
public function index()
{
$model = new RoleModel();
$data['roles'] = $model->findAll();
return view('roles/index', $data);
}
public function create()
{
return view('roles/create');
}
public function store()
{
$model = new RoleModel();
$model->save([
'name' => $this->request->getPost('name'),
'description' => $this->request->getPost('description'),
]);
return redirect()->to('/roles');
}
}
In PermissionController.php
file:
<?php namespace App\Controllers;
use App\Models\PermissionModel;
class PermissionController extends BaseController
{
public function index()
{
$model = new PermissionModel();
$data['permissions'] = $model->findAll();
return view('permissions/index', $data);
}
public function create()
{
return view('permissions/create');
}
public function store()
{
$model = new PermissionModel();
$model->save([
'name' => $this->request->getPost('name'),
'description' => $this->request->getPost('description'),
]);
return redirect()->to('/permissions');
}
}
Step 5 – Implement Role-Based Access Control
Go to App/Libraries
directory and create AccessControl.php
(Library) file, and implement role based access control logic in it:
<?php namespace App\Libraries;
use App\Models\UserModel;
use App\Models\RoleModel;
use App\Models\PermissionModel;
class AccessControl
{
protected $userModel;
protected $roleModel;
protected $permissionModel;
public function __construct()
{
$this->userModel = new UserModel();
$this->roleModel = new RoleModel();
$this->permissionModel = new PermissionModel();
}
public function canAccess($userId, $permissionName)
{
$roleId = $this->userModel->getUserRole($userId);
if (!$roleId) {
return false;
}
$permissions = $this->permissionModel->select('permissions.name')
->join('role_permissions', 'permissions.id = role_permissions.permission_id')
->where('role_permissions.role_id', $roleId)
->findColumn('name');
return in_array($permissionName, $permissions);
}
}
Step 6 – Use Middleware for Access Control
Create filters in the middleware to enforce user access to application features based on permissions. Edit App/Filters/AccessControlFilter.php
file, and add the following code in it:
<?php namespace App\Filters;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;
use App\Libraries\AccessControl;
class AccessControlFilter implements FilterInterface
{
protected $accessControl;
public function __construct()
{
$this->accessControl = new AccessControl();
}
public function before(RequestInterface $request, $arguments = null)
{
$userId = session()->get('user_id');
$requiredPermission = $arguments[0] ?? '';
if (!$this->accessControl->canAccess($userId, $requiredPermission)) {
return redirect()->to('/no-access');
}
}
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// Do something here if needed
}
}
Step 7 – Set Up Routes and Filters
Edit app/Config/Filters.php
file, and add filter in it:
public $aliases = [
// Other filters...
'accessControl' => \App\Filters\AccessControlFilter::class,
];
Edit app/Config/Routes.php
file, and add routes in it:
$routes->get('/admin', 'AdminController::index', ['filter' => 'accessControl:admin_access']);
$routes->get('/profile', 'UserController::profile', ['filter' => 'accessControl:user_access']);
Step 8 – Create Views
Go to app/views
directory and create views file with roles and permissions.
Step 9 – Test the Application
Now setup roles and permissions per user. Assign permissions to users according to roles. And test this application.