Article

Implement Role-Based Access Control with PHP and MySQL on Ubuntu 20.04 Server

Author: Francis Ndungu

Last Updated: Fri, Oct 15, 2021
MySQL and MariaDB PHP Programming Ubuntu

Introduction

When designing an internal application, you must provide a form of access control through authentication and authorization. You use authentication to confirm whether users have the right to access your system by validating their usernames and passwords against their account values. On the other hand, authorization allows you to verify whether an authenticated user has the correct permission to access a particular resource. For instance, to delete or update a product.

While the MySQL database provides roles-based permissions, it is not practically possible to create database usernames for all users accessing your system unless they're connecting directly via the command-line interface. In an optimal PHP application, your scripts connect to the database server through a single MySQL user account. Then, it is your job to code an access control functionality using the different features of PHP and MySQL.

In this guide, you'll set up a role-based permission feature for your application with PHP and MySQL on your Ubuntu 20.04 server. Instead of assigning permissions to users directly, you'll group the permissions and assign them to a role. Then, once you tie up users to a role, they will automatically inherit the privileges assigned to that role.

Prerequisites

To complete this guide, you require:

1. Set Up a Database and User Account

SSH to your server to complete the following steps.

  1. Log in to your MySQL database server as root.

    $ sudo mysql -u root -p
    
  2. Enter your root password when prompted and press ENTER to proceed. Then, set up a sample erp_db database and user account. Replace EXAMPLE_PASSWORD with a strong value.

    mysql> CREATE DATABASE erp_db;
           CREATE USER 'erp_db_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'EXAMPLE_PASSWORD';
           GRANT ALL PRIVILEGES ON erp_db.* TO 'erp_db_user'@'localhost';           
           FLUSH PRIVILEGES;
    
  3. Switch to the new erp_db database.

    mysql> USE erp_db;
    

2. Create a products Table

In this sample application, you'll create a products table to store items available for sale in your business. This is a simple resource that you want to protect in your application. While only authenticated users will be able to access it, you don't want anyone to mess around with the price list or probably edit the product names unless they have the right permissions.

To achieve this form of security, you'll later create roles and permissions and define what a specific user can do in regards to the products resource. For instance, you can allow all users to list the items in the products resource and only restrict product updates and deletion to a few administrators.

  1. Create the products table.

    mysql> CREATE TABLE products (
               product_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               product_name VARCHAR(50),
               retail_price DOUBLE   
           ) ENGINE = InnoDB;
    
  2. Populate the products table with some records.

    mysql> INSERT INTO products(product_name, retail_price) VALUES ('VIRTUAL PRIVATE SERVER', 6);
           INSERT INTO products(product_name, retail_price) VALUES ('BARE METAL', 185);
           INSERT INTO products(product_name, retail_price) VALUES ('DEDICATED CLOUD', 60);
    
  3. Confirm the entries in the products table.

    mysql> SELECT
               product_id,
               product_name,
               retail_price   
           FROM products;
    

    Output.

    +------------+------------------------+--------------+
    | product_id | product_name           | retail_price |
    +------------+------------------------+--------------+
    |          1 | VIRTUAL PRIVATE SERVER |            6 |
    |          2 | BARE METAL             |          185 |
    |          3 | DEDICATED CLOUD        |           60 |
    +------------+------------------------+--------------+
    3 rows in set (0.00 sec)
    

3. Create the Role-based Access Control Tables

You require 3 MySQL tables to create an access control module for your PHP application.

  1. Create the system_permissions table. This table stores your application's permissions in a human-readable format.

    mysql> CREATE TABLE system_permissions (
               permission_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               permission_name VARCHAR(50)               
           ) ENGINE = InnoDB;
    
  2. Populate the system_permissions table. Since you only have 1 resource for demonstration purposes, you'll create 4 permissions. In a real-life application with lots of resources, you might require hundreds or even thousands of permissions depending on the complexity of the software.

    mysql> INSERT INTO system_permissions(permission_name) VALUES ('CREATE PRODUCT');
           INSERT INTO system_permissions(permission_name) VALUES ('EDIT PRODUCT');
           INSERT INTO system_permissions(permission_name) VALUES ('DELETE PRODUCT');
           INSERT INTO system_permissions(permission_name) VALUES ('LIST PRODUCTS');
    
  3. Verify the new permissions.

    mysql> SELECT
               permission_id,
               permission_name               
           FROM system_permissions;
    

    Output.

    +---------------+-----------------+
    | permission_id | permission_name |
    +---------------+-----------------+
    |             1 | CREATE PRODUCT  |
    |             2 | EDIT PRODUCT    |
    |             3 | DELETE PRODUCT  |
    |             4 | LIST PRODUCTS   |
    +---------------+-----------------+
    4 rows in set (0.00 sec)
    
  4. Create a roles table. A role allows you to group multiple permissions together.

    mysql> CREATE TABLE roles (
               role_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               role_name VARCHAR(50)               
           ) ENGINE = InnoDB;
    
  5. Populate the roles table with 3 records. You'll later assign permissions to these roles.

    mysql> INSERT INTO roles(role_name) VALUES ('ERP MANAGER');
           INSERT INTO roles(role_name) VALUES ('LEVEL 1 ADMIN');
           INSERT INTO roles(role_name) VALUES ('ERP CLERKS');
    
  6. Confirm the records from the roles table.

    mysql> SELECT
               role_id,
               role_name               
           FROM roles;
    

    Output.

    +---------+---------------+
    | role_id | role_name     |
    +---------+---------------+
    |       1 | ERP MANAGER   |
    |       2 | LEVEL 1 ADMIN |
    |       3 | ERP CLERKS    |
    +---------+---------------+
    3 rows in set (0.00 sec)
    

    Please note: Although you've defined 3 roles in this sample application, there is no limit to the number of system users that you can later tie to them. For instance, in a real-life scenario, you can have 5 ERP MANAGERs, 12 LEVEL 1 ADMINs, and 125 ERP clerks.

  7. Next, create a system_permission_to_roles table. You'll use this table to assign permissions to each role. Here, don't repeat the names of the permission and roles. You'll simply use the role_id and permission_id to optimize the table and avoid bloating your database. In simple terms, you're creating a many-to-many relationship between the roles and system_permissions tables. This is because a single role can have many different permissions and you can assign single permission to many different roles.

    mysql> CREATE TABLE system_permission_to_roles (
               ref_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               role_id BIGINT,
               permission_id BIGINT                   
           ) ENGINE = InnoDB;
    
  8. For now, you'll create the following roles and permissions for your sample application.

    • ERP MANAGER: Has a right to CREATE PRODUCT, EDIT PRODUCT, LIST PRODUCTS, and DELETE PRODUCT.
    • LEVEL 1 ADMIN: Has a right to CREATE PRODUCT and LIST PRODUCTS.
    • ERP CLERKS: Has a right to LIST PRODUCTS only.

    Add those roles and their respective permissions into the system_permission_to_roles table.

    The ERP MANAGER's permissions:

    mysql> INSERT INTO system_permission_to_roles (role_id, permission_id) VALUES (1, 1);
           INSERT INTO system_permission_to_roles (role_id, permission_id) VALUES (1, 2); 
           INSERT INTO system_permission_to_roles (role_id, permission_id) VALUES (1, 3);    
           INSERT INTO system_permission_to_roles (role_id, permission_id) VALUES (1, 4); 
    

    The LEVEL 1 ADMIN's permissions:

    mysql> INSERT INTO system_permission_to_roles (role_id, permission_id) VALUES (2, 1);  
           INSERT INTO system_permission_to_roles (role_id, permission_id) VALUES (2, 4); 
    

    The ERP CLERKS' permissions:

    mysql> INSERT INTO system_permission_to_roles (role_id, permission_id) VALUES (3, 4);
    

4. Create the Users Data Tables

To log in(authenticate) to your system, a system user will require a username and a password. To provide the access control functionality, you'll later in this guide assign such users some roles depending on the privileges that you want to assign to them(authorization).

  1. Create a system_users table. This table stores the real names, usernames, and hashed passwords for the system users.

    mysql> CREATE TABLE system_users (
               user_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               first_name VARCHAR(50),
               last_name VARCHAR(50),
               username VARCHAR(50),
               pwd   VARCHAR(255)            
           ) ENGINE = InnoDB;
    
  2. Add some records into the system_users table. For demonstration purposes, all the 3 users are using the same password(EXAMPLE_PASSWORD) hashed with the bcrypt library. In a production environment, you should design a register script to allow users to sign up to your application and this is where you should hash the passwords before posting them in the system_users table using the syntax `passwordhash(SAMPLEPASSWORD, PASSWORD_BCRYPT).

    For now, populate the system_users table with the pre-hashed EXAMPLE_PASSWORD password.

    mysql> INSERT INTO system_users (first_name, last_name, username, pwd) VALUES ('JOHN', 'DOE', 'john_doe','$2a$12$JOe5OFLD9dFkI.KJ1k9TP.ixWX/YtYArB/Yv.A8XSeIcCBkIlPvoi');
           INSERT INTO system_users (first_name, last_name, username, pwd) VALUES ('MARY', 'SMITH', 'mary_smith','$2a$12$JOe5OFLD9dFkI.KJ1k9TP.ixWX/YtYArB/Yv.A8XSeIcCBkIlPvoi');
           INSERT INTO system_users (first_name, last_name, username, pwd) VALUES ('STEVE', 'RIA', 'steve_ria','$2a$12$JOe5OFLD9dFkI.KJ1k9TP.ixWX/YtYArB/Yv.A8XSeIcCBkIlPvoi');  
    
  3. Confirm the records in the system_users table.

    mysql> SELECT
                 user_id ,
                 first_name,
                 last_name,
                 username,
                 pwd
            FROM system_users;
    

    Output.

    +---------+------------+-----------+------------+--------------------------------------------------------------+
    | user_id | first_name | last_name | username   | pwd                                                          |
    +---------+------------+-----------+------------+--------------------------------------------------------------+
    |       1 | JOHN       | DOE       | john_doe   | $2a$12$JOe5OFLD9dFkI.KJ1k9TP.ixWX/YtYArB/Yv.A8XSeIcCBkIlPvoi |
    |       2 | MARY       | SMITH     | mary_smith | $2a$12$JOe5OFLD9dFkI.KJ1k9TP.ixWX/YtYArB/Yv.A8XSeIcCBkIlPvoi |
    |       3 | STEVE      | RIA       | steve_ria  | $2a$12$JOe5OFLD9dFkI.KJ1k9TP.ixWX/YtYArB/Yv.A8XSeIcCBkIlPvoi |
    +---------+------------+-----------+------------+--------------------------------------------------------------+
    3 rows in set (0.00 sec)          
    
  4. Create a system_users_to_roles table. You'll use this table to tie up users to the roles you've created in the previous steps.

    mysql> CREATE TABLE system_users_to_roles (
               ref_id BIGINT NOT NULL AUTO_INCREMENT  PRIMARY KEY,
               user_id BIGINT,
               role_id BIGINT                    
           ) ENGINE = InnoDB;
    
  5. Assign users to the respective roles depending on the permissions that you want to inherit..

    Assign JOHN DOE to the ERP MANAGER's role:

    mysql> INSERT INTO system_users_to_roles (user_id,role_id) VALUES (1, 1);
    

    Assign MARY SMITH to the LEVEL 1 ADMIN role:

    mysql> INSERT INTO system_users_to_roles (user_id,role_id) VALUES (2, 2);
    

    Assign STEVE RIA to the ERP CLERKs role:

    mysql> INSERT INTO system_users_to_roles (user_id,role_id) VALUES (3, 3);
    

    Verify if you've assigned the roles correctly by running a JOIN statement against the two tables.

    mysql> SELECT
               system_users.user_id,
               system_users.username,
               system_users.first_name,
               system_users.last_name,                 
               system_users_to_roles.role_id,
               roles.role_name
           FROM system_users
           LEFT JOIN system_users_to_roles
           ON system_users.user_id = system_users_to_roles.user_id
           LEFT JOIN roles
           ON system_users_to_roles.role_id = roles.role_id;
    

    As you can see from the following output, you were able to match the users to the respective roles correctly.

    +---------+------------+------------+-----------+---------+---------------+
    | user_id | username   | first_name | last_name | role_id | role_name     |
    +---------+------------+------------+-----------+---------+---------------+
    |       1 | john_doe   | JOHN       | DOE       |       1 | ERP MANAGER   |
    |       2 | mary_smith | MARY       | SMITH     |       2 | LEVEL 1 ADMIN |
    |       3 | steve_ria  | STEVE      | RIA       |       3 | ERP CLERKS    |
    +---------+------------+------------+-----------+---------+---------------+
    3 rows in set (0.00 sec)  
    
  6. Log out from the MySQL server.

    mysql> EXIT;                
    

5. Create the PHP Scripts

You've set up the appropriate data tables for managing access control in your MySQL database. You'll now create a web resource using PHP. When users access your sample application, you'll only allow them to perform tasks depending on the permissions tied to their assigned roles.

  1. Create a new db_function.php file under the root directory of your web server.

    $ sudo nano /var/www/html/db_function.php
    
  2. Paste the information below into the file. In this file, you're defining variables to connect to your database via the PHP Data Object(PDO). This file has a single pdoConnection() function that you'll use later in this guide. Change EXAMPLE_PASSWORD with the correct password.

    <?php
    
    function pdoConnection() {
    
        try {
    
            $db_name     = 'erp_db';
            $db_user     = 'erp_db_user';
            $db_password = 'EXAMPLE_PASSWORD';
            $db_host     = 'localhost';
    
            $pdo = new PDO('mysql:host=' . $db_host . '; dbname=' . $db_name, $db_user, $db_password);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
            return $pdo;
    
           } catch (PDOException $e) {
               echo $e->getMessage();
           }
    }
    
  3. Save and close the file.

  4. Next, create an authentications.php script. This script handles the authentication part of your application. It checks whether a user has a valid username and password.

    $ sudo nano /var/www/html/authentications.php
    
  5. Paste the following information into the file. In this file, you'll retrieve the user_id from the MySQL database and assign it to the variable $user_id which you'll later use to check the permissions that a user has in the system. You're accomplishing this using the statement $user_id = $user_details['user_id'];.

    <?php
    
         if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
             header("HTTP/1.0 401 Unauthorized");
             echo '"{"error": "Authentication failed."}';
             exit();             
         } else {
             $username = $_SERVER['PHP_AUTH_USER'];
             $password = $_SERVER['PHP_AUTH_PW'];
         }
    
        $sql_authenticate = 'select * from system_users where username = :username';
    
        $data = [
                'username' => $username
                ];
    
        $stmt = $pdo->prepare($sql_authenticate);
        $stmt->execute($data); 
    
        $user_details = [];
    
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {         
            $user_details  = $row;          
        }  
    
       if (password_verify($password, $user_details['pwd']) == true) {
           $user_id =  $user_details['user_id'];                           
       } else {
           header("HTTP/1.0 401 Unauthorized");
           echo '{"error": "Invalid username or password."}';
           exit();
       } 
    
  6. Save and close the file.

  7. Create a system_permissions.php script.

    $ sudo nano /var/www/html/system_permissions.php
    
  8. Paste the information below into the file. In this file, you're checking if a user has the right permissions to perform a certain task by running a JOIN statement against the system_users_to_roles and system_permission_to_roles tables. This function accepts two variables. To check if authenticated users have permissions to perform a certain task, you simply send their user_id that you've retrieved from the authentications.php script and the permission_id of a resource to this function. The function then returns either true or false and allows you to either restrict or grant access to the resource.

    <?php
    
        function checkPermissions($user_id, $permission_id) { 
    
            require_once('db_function.php');
    
            $pdo = pdoConnection();     
    
            try {
    
                $sql  = 'select
                         count(*) as total_permissions
                         from system_permission_to_roles
                         left join system_users_to_roles
                         on system_permission_to_roles.role_id = system_users_to_roles.role_id
                         where system_users_to_roles.user_id = :user_id
                         and permission_id = :permission_id
                        '; 
    
                 $data = [
                         'user_id'       => $user_id,
                         'permission_id' => $permission_id
                         ];  
    
                 $stmt = $pdo->prepare($sql);
                 $stmt->execute($data);
                 $row  = $stmt->fetch();
    
                 $authorized = ''; 
    
                 if ($row['total_permissions'] > 0) {
                     $authorized = "true";
                 } else {
                     $authorized = "false";
                 }
    
                 return $authorized;
    
            } catch (Exception $e) {
                echo $e->getMessage();
            }
    }
    
  9. Save and close the file.

  10. Create the products.php resource file. This is the main endpoint that you want to secure with authentication and authorization features. Users accessing your application will request this page through a client application(For example, a mobile app or desktop software). For this guide, you'll later use curl to retrieve the page.

    $ sudo nano /var/www/html/products.php
    
  11. Paste the information below into the file. Please note, this guide doesn't address data validation in your PHP files. When working in a production environment, consider a form of data validation. To understand the CRUD (Create, Read, Update, or Delete)function the user wants to perform in your application, you're using the statement $http_verb = $_SERVER['REQUEST_METHOD'];.

    Then, you're checking if a user is authorized to perform the task using the statement if (checkPermissions($user_id, 1) == "false") {...}.

    <?php 
    
        require_once('db_function.php');
        require_once('system_permissions.php');
    
        $pdo       = pdoConnection();
        $http_verb = $_SERVER['REQUEST_METHOD'];
        $params    = json_decode(file_get_contents('php://input')); 
    
        require_once('authentications.php');
    
        if ($http_verb == 'POST') {
    
            if (checkPermissions($user_id, 1) == "false") {
                header("HTTP/1.0 403 Forbidden");
                echo '{"error": "You do not have permissions to create a product."}' . '\n';
                exit();
            }
    
            $sql = 'insert into products (
                        product_name, 
                        retail_price
                    ) values (
                        :product_name, 
                        :retail_price
                    )';
    
            $data = [ 
                    'product_name' => $params->product_name,
                    'retail_price' => $params->retail_price
                    ];   
    
            $stmt = $pdo->prepare($sql);
            $stmt->execute($data);  
    
            echo '{"message": "Product created successfully."}' . '\n';
    
        } elseif ($http_verb == 'GET') {
    
            $me = checkPermissions($user_id, 4);
    
            if (checkPermissions($user_id, 4) == "false") {
                header("HTTP/1.0 403 Forbidden");
                echo '{"error": "You do not have permissions to list products."}' . '\n';
                exit();
            }
    
             $sql  = 'select * from products';  
    
             $stmt = $pdo->prepare($sql);
             $stmt->execute(); 
    
             $data = [];
    
             while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                 $data[] = $row;                    
             }
    
             $reponse = [];
             $response['data'] = $data;
    
             echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
    
        } elseif ($http_verb == 'PUT') {
    
            if (checkPermissions($user_id, 2) == "false") {
                header("HTTP/1.0 403 Forbidden");
                echo '{"error": "You do not have permissions to update a product."}' . '\n';
                exit();
            }
    
            $sql = 'update products set 
                        product_name = :product_name, 
                        retail_price = :retail_price
                    where product_id = :product_id
                    ';
    
            $data = [ 
                    'product_id'   => $params->product_id, 
                    'product_name' => $params->product_name,
                    'retail_price' => $params->retail_price              
                    ];   
    
            $stmt = $pdo->prepare($sql);
            $stmt->execute($data); 
    
            echo '{"message": "Product updated successfully"}' . '\n';
    
        } elseif ($http_verb == 'DELETE') { 
    
            if (checkPermissions($user_id, 3) == "false") {
                header("HTTP/1.0 403 Forbidden");
                echo '{"error": "You do not have permissions to delete a product."}';
                exit();
            }
    
            $sql = 'delete from products
                    where product_id = :product_id
                    limit 1
                    ';
    
            $data = [ 
                    'product_id' => $params->product_id                
                    ];   
    
            $stmt = $pdo->prepare($sql);
            $stmt->execute($data); 
    
            echo '{"message": "Product deleted successfully."}' . '\n';
        }
    
  12. Save and close the file.

6. Test the Application

Your database tables and PHP scripts are now in place.

  1. Use curl to access the URL http://localhost/products.php. Begin by entering the wrong credentials to check whether the authentication logic is working.

    $ curl -u john_doe:WRONG_PASSWORD http://localhost/products.php
    
  2. Since you've entered the WRONG_PASSWORD for user john_doe, you should receive the following error.

    {"error": "Invalid username or password."}
    
  3. Next, attempt to list products using the 3 sample users. This time around, use the correct password. In this case, EXAMPLE_PASSWORD.

    $ curl -u john_doe:EXAMPLE_PASSWORD http://localhost/products.php
    $ curl -u mary_smith:EXAMPLE_PASSWORD http://localhost/products.php
    $ curl -u steve_ria:EXAMPLE_PASSWORD http://localhost/products.php
    
  4. Since all the 3 users have the 'LIST PRODUCTS' permission, you should get the following output after running the above curl commands.

    {
        "data": [
            {
                "product_id": "1",
                "product_name": "VIRTUAL PRIVATE SERVER",
                "retail_price": "6"
            },
            {
                "product_id": "2",
                "product_name": "BARE METAL",
                "retail_price": "185"
            },
            {
                "product_id": "3",
                "product_name": "DEDICATED CLOUD",
                "retail_price": "60"
            }
        ]
    }
    
  5. Next, you've only granted the CREATE PRODUCT permission to john_doe and mary_smith. Execute the following curl command using those users' credentials to add more products into your database.

    $ curl -u john_doe:EXAMPLE_PASSWORD --header "Content-Type: application/json" --request POST --data '{"product_name":"SAMPLE_PRODUCT_4","retail_price":"99.99"}' http://localhost/products.php
    $ curl -u mary_smith:EXAMPLE_PASSWORD --header "Content-Type: application/json" --request POST --data '{"product_name":"SAMPLE_PRODUCT_5","retail_price":"299.20"}' http://localhost/products.php
    

    Since the 2 users have the right permission, you should get the output below.

    ...
    {"message": "Product created successfully."}
    
  6. Verify if you've successfully inserted the products into the database by listing them one more time.

    $ curl -u john_doe:EXAMPLE_PASSWORD http://localhost/products.php
    

    As you can see from the output below, you've added the SAMPLE_PRODUCT_4 and SAMPLE_PRODUCT_5 into the products table.

    {
        "data": [
            {
                "product_id": "1",
                "product_name": "VIRTUAL PRIVATE SERVER",
                "retail_price": "6"
            },
            {
                "product_id": "2",
                "product_name": "BARE METAL",
                "retail_price": "185"
            },
            {
                "product_id": "3",
                "product_name": "DEDICATED CLOUD",
                "retail_price": "60"
            },
            {
                "product_id": "4",
                "product_name": "SAMPLE_PRODUCT_4",
                "retail_price": "99.99"
            },
            {
                "product_id": "5",
                "product_name": "SAMPLE_PRODUCT_5",
                "retail_price": "299.2"
            }
       ]
    }
    
  7. Attempt to create a product with steve_ria's credentials.

    $ curl -u steve_ria:EXAMPLE_PASSWORD --header "Content-Type: application/json" --request POST --data '{"product_name":"SAMPLE_PRODUCT_6","retail_price":"340.63"}' http://localhost/products.php
    

    Since you've not granted steve_ria's the CREATE PRODUCT permission, the operation should fail with the following error.

    {"error": "You do not have permissions to create a product."}
    
  8. Next, only john_doe( The ERP MANAGER) can update or delete products. Execute the commands below with his credentials.

    $ curl -u john_doe:EXAMPLE_PASSWORD --header "Content-Type: application/json" --request PUT --data '{"product_id":"1","product_name":"VPS MACHINE","retail_price":"6.00"}' http://localhost/products.php
    $ curl -u john_doe:EXAMPLE_PASSWORD --header "Content-Type: application/json" --request DELETE --data '{"product_id":"5"}' http://localhost/products.php    
    

    You should be able to update and delete the product and get the following responses.

    {"message": "Product updated successfully"}
    {"message": "Product deleted successfully."}
    

    Verify whether you've updated and deleted the products by listing the products.

     $ curl -u john_doe:EXAMPLE_PASSWORD http://localhost/products.php
    

    You've indeed updated the first product from VIRTUAL PRIVATE SERVER to VPS MACHINE and you've successfully deleted SAMPLE_PRODUCT_5.

        "data": [
            {
                "product_id": "1",
                "product_name": "VPS MACHINE",
                "retail_price": "6"
            },
            {
                "product_id": "2",
                "product_name": "BARE METAL",
                "retail_price": "185"
            },
            {
                "product_id": "3",
                "product_name": "DEDICATED CLOUD",
                "retail_price": "60"
            },
            {
                "product_id": "4",
                "product_name": "SAMPLE_PRODUCT_4",
                "retail_price": "99.99"
            }
        ]
    }
    

    However, if you attempt to either update or delete a product with the mary_smith's or steve_ria's credentials, the operations should fail.

    $ curl -u mary_smith:EXAMPLE_PASSWORD --header "Content-Type: application/json" --request PUT --data '{"product_ID":"1","product_name":"VPS MACHINE","retail_price":"6.00"}' http://localhost/products.php  
    $ curl -u mary_smith:EXAMPLE_PASSWORD --header "Content-Type: application/json" --request DELETE --data '{"product_ID":"5"}' http://localhost/products.php
    $ curl -u steve_ria:EXAMPLE_PASSWORD --header "Content-Type: application/json" --request PUT --data '{"product_ID":"1","product_name":"VPS MACHINE","retail_price":"6.00"}' http://localhost/products.php  
    $ curl -u steve_ria:EXAMPLE_PASSWORD --header "Content-Type: application/json" --request DELETE --data '{"product_ID":"5"}' http://localhost/products.php     
    

    Output.

    {"error": "You do not have permissions to update a product."}
    {"error": "You do not have permissions to delete a product."}
    {"error": "You do not have permissions to update a product."}
    {"error": "You do not have permissions to update a product."}
    

    Your permission settings are now working as expected.

7. Use Cases for Role-Based Access Control

You've seen the power of role-based access control in your application. Here are a few real-life scenarios where the technology is used.

  • In a banking application, cashiers have the right to deposit and withdrawal money in the system. However, the reversal right for erroneously entered data may be preserved to supervisors only. Also, only a loan officer can disburse loans to avoid fraud.

  • In a content management system where users are paid to submit articles to a blog, an editor may be assigned the right to approve the articles while an accountant may be the only authorized person to make payments for the completed articles.

  • In a grocery store software, cashiers can ring sales and check their end-of-day totals but they can't delete a sales record unless it is done by the manager(For instance, during a return).

Conclusion

In this guide, you've implemented role-based access control with PHP and MySQL on your Ubuntu 20.04 server. Implement the knowledge in this guide to offer tight authentication and authorization when designing your next PHP project.

Refer to the documents below for more information on using PHP and PDO.

Want to contribute?

You could earn up to $600 by adding new articles