Friday, October 30, 2020

Create, Update & Delete record with AJAX in DatTables using PHP

With the use of the DataTables jQuery plugin, you can list your records in pagination format.

You can add HTML elements like – buttons, link, image, etc with a record.

For this need to pass element in HTML string format from the PHP script.


NOTE – I am using the Bootstrap modal to update a record.


Contents

  1. Table structure
  2. Configuration
  3. Download & Include
  4. HTML
  5. PHP
  6. jQuery
  7. Output
  8. Conclusion

1. Table structure

Create users table and I added some records.

CREATE TABLE `users` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(80) NOT NULL, 
  `gender` varchar(10) NOT NULL,
  `city` varchar(80) NOT NULL,
  `email` varchar(80) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2. Configuration

Create a config.php for the database connection.

Completed Code

<?php

$host = "localhost"; /* Host name */
$user = "root"; /* User */
$password = ""; /* Password */
$dbname = "tutorial"; /* Database name */

$con = mysqli_connect($host, $user, $password,$dbname);
// Check connection
if (!$con) {
  die("Connection failed: " . mysqli_connect_error());
}

3. Download & Include

  • Download Datatables from here and Bootstrap from here.
  • Include datatables.min.cssbootstrap.min.css, jQuery library, bootstrap.min.js, and datatables.min.js in <head> section.
  • You can also use CDN.
<!-- Datatable CSS -->
<link href='//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css' rel='stylesheet' type='text/css'>

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" >

<!-- jQuery Library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<!-- Bootstrap CSS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" ></script>

<!-- Datatable JS -->
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>

4. HTML

Create <div id="updateModal" > modal for update user details. Created a hidden field to store edit user id and <button id="btn_save"> to update user on click.

Display users list in <table id='userTable' >. On the last column, display the edit and delete button.

Completed Code

<!doctype html>
<html>
<head>
   <title>Edit delete DataTables record with AJAX and PHP</title>

   <meta name="viewport" content="width=device-width, initial-scale=1.0">

   <!-- Datatable CSS -->
   <link href='DataTables/datatables.min.css' rel='stylesheet' type='text/css'>

   <!-- Bootstrap CSS -->
   <link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.min.css">

   <!-- jQuery Library -->
   <script src="jquery-3.5.1.min.js"></script>

   <!-- Bootstrap JS -->
   <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>

   <!-- Datatable JS -->
   <script src="DataTables/datatables.min.js"></script>

</head>
<body >

   <div class='container'>

     <!-- Modal -->
     <div id="updateModal" class="modal fade" role="dialog">
       <div class="modal-dialog">

         <!-- Modal content-->
         <div class="modal-content">
           <div class="modal-header">
             <h4 class="modal-title">Update</h4>
             <button type="button" class="close" data-dismiss="modal">&times;</button> 
           </div>
           <div class="modal-body">
             <div class="form-group">
               <label for="name" >Name</label>
               <input type="text" class="form-control" id="name" placeholder="Enter name" required> 
             </div>
             <div class="form-group">
               <label for="email" >Email</label> 
               <input type="email" class="form-control" id="email" placeholder="Enter email"> 
             </div> 
             <div class="form-group">
               <label for="gender" >Gender</label>
               <select id='gender' class="form-control">
                 <option value='male'>Male</option>
                 <option value='female'>Female</option>
               </select> 
             </div> 
             <div class="form-group">
               <label for="city" >City</label> 
               <input type="text" class="form-control" id="city" placeholder="Enter city"> 
             </div>

           </div>
           <div class="modal-footer">
             <input type="hidden" id="txt_userid" value="0">
             <button type="button" class="btn btn-success btn-sm" id="btn_save">Save</button>
             <button type="button" class="btn btn-default btn-sm" data-dismiss="modal">Close</button>
           </div>
         </div>

       </div>
     </div>

     <!-- Table -->
     <table id='userTable' class='display dataTable' width='100%'>
       <thead>
         <tr>
           <th>Name</th>
           <th>Email</th>
           <th>Gender</th>
           <th>City</th>
           <th>Action</th>
         </tr>
       </thead>
     </table>

   </div>

</body>
</html>

5. PHP

Create an ajaxfile.php file for handling AJAX requests.

Handle 4 requests –

If $request == 1 – Return DataTable response.

Read DataTable POST values and assign them in variables.

If $search is not empty then prepare search query and assign in $searchQuery variable.

Count total records with and without search filter and assign in variables. Fetch records from users table where pass $searchQuery in WHERE clause and specify ORDER BY and LIMIT.

Loop on the fetched records. Display update and delete buttons in DataTable using HTML string.

    • Create an update button and assign in $updateButton. In the button add 'updateUser' class and use data-id attribute to store user id. Add data-toggle and data-target attribute to open #updateModal modal.
    • Similarly, create delete button and assign in $deleteButton. In the button add 'deleteUser' class and use data-id attribute to store user id.

Concat $updateButton and $deleteButton and assign in $action variable.

Initialize $response Array with required values. Here, pass the $action in 'action' key.

Return $response Array in JSON format.

If $request == 2 – Return user details by id.

Assign $_POST['id'] to $id variable. Fetch a record from users table by id. If the number of fetched record is greater than 0 then read field values and initialize $response Array. Return an Array in JSON format that contains array("status" => 1,"data" => $response).

If the number of fetched record is 0 then Return an Array in JSON format that contains array("status" => 1).

If $request == 3 – Update field values by id.

Assign $_POST['id'] to $id variable. If $id is greater than 0 then read POST value and assign in a variable.

Check if $id is exists in the users table. If exists then check if variables are not empty then update a record by id and return Array in JSON format. Array contains array("status" => 1,"message" => "Record updated."). If variables are empty then return array("status" => 0,"message" => "Please fill all fields.") in JSON format.

If $id is not exists then return array("status" => 0,"message" => "Invalid ID.") in JSON format.

If $request == 4 – Delete a record by id.

Assign $_POST['id'] to $id variable. If $id is greater than 0 then read POST value and assign in a variable.

Check if $id is exists in the users table. If exist then delete a record from users table by id and return 1 otherwise return 0.

Completed Code

<?php
include 'config.php';

$request = 1;
if(isset($_POST['request'])){
   $request = $_POST['request'];
}

// DataTable data
if($request == 1){
   ## Read value
   $draw = $_POST['draw'];
   $row = $_POST['start'];
   $rowperpage = $_POST['length']; // Rows display per page
   $columnIndex = $_POST['order'][0]['column']; // Column index
   $columnName = $_POST['columns'][$columnIndex]['data']; // Column name
   $columnSortOrder = $_POST['order'][0]['dir']; // asc or desc

   $searchValue = mysqli_escape_string($con,$_POST['search']['value']); // Search value

   ## Search 
   $searchQuery = " ";
   if($searchValue != ''){
      $searchQuery = " and (name like '%".$searchValue."%' or 
         email like '%".$searchValue."%' or 
         city like'%".$searchValue."%' ) ";
   }

   ## Total number of records without filtering
   $sel = mysqli_query($con,"select count(*) as allcount from users");
   $records = mysqli_fetch_assoc($sel);
   $totalRecords = $records['allcount'];

   ## Total number of records with filtering
   $sel = mysqli_query($con,"select count(*) as allcount from users WHERE 1 ".$searchQuery);
   $records = mysqli_fetch_assoc($sel);
   $totalRecordwithFilter = $records['allcount'];

   ## Fetch records
   $empQuery = "select * from users WHERE 1 ".$searchQuery." order by ".$columnName." ".$columnSortOrder." limit ".$row.",".$rowperpage;
   $empRecords = mysqli_query($con, $empQuery);
   $data = array();

   while ($row = mysqli_fetch_assoc($empRecords)) {

     // Update Button
     $updateButton = "<button class='btn btn-sm btn-info updateUser' data-id='".$row['id']."' data-toggle='modal' data-target='#updateModal' >Update</button>";

     // Delete Button
     $deleteButton = "<button class='btn btn-sm btn-danger deleteUser' data-id='".$row['id']."'>Delete</button>";

     $action = $updateButton." ".$deleteButton;

     $data[] = array(
       "name" => $row['name'],
       "email" => $row['email'],
       "gender" => $row['gender'],
       "city" => $row['city'],
       "action" => $action
     );
   }

   ## Response
   $response = array(
     "draw" => intval($draw),
     "iTotalRecords" => $totalRecords,
     "iTotalDisplayRecords" => $totalRecordwithFilter,
     "aaData" => $data
   );

   echo json_encode($response);
   exit;
}

// Fetch user details
if($request == 2){
   $id = 0;

   if(isset($_POST['id'])){
      $id = mysqli_escape_string($con,$_POST['id']);
   }

   $record = mysqli_query($con,"SELECT * FROM users WHERE id=".$id);

   $response = array();

   if(mysqli_num_rows($record) > 0){
      $row = mysqli_fetch_assoc($record);
      $response = array(
         "name" => $row['name'],
         "email" => $row['email'],
         "gender" => $row['gender'],
         "city" => $row['city'],
      );

      echo json_encode( array("status" => 1,"data" => $response) );
      exit;
   }else{
      echo json_encode( array("status" => 0) );
      exit;
   }
}

// Update user
if($request == 3){
   $id = 0;

   if(isset($_POST['id'])){
      $id = mysqli_escape_string($con,$_POST['id']);
   }

   // Check id
   $record = mysqli_query($con,"SELECT id FROM users WHERE id=".$id);
   if(mysqli_num_rows($record) > 0){
 
      $name = mysqli_escape_string($con,trim($_POST['name']));
      $email = mysqli_escape_string($con,trim($_POST['email']));
      $gender = mysqli_escape_string($con,trim($_POST['gender']));
      $city = mysqli_escape_string($con,trim($_POST['city']));

      if( $name != '' && $email != '' && $gender != '' && $city != '' ){

         mysqli_query($con,"UPDATE users SET name='".$name."',email='".$email."',gender='".$gender."',city='".$city."' WHERE id=".$id);

         echo json_encode( array("status" => 1,"message" => "Record updated.") );
         exit;
      }else{
         echo json_encode( array("status" => 0,"message" => "Please fill all fields.") );
         exit;
      }

   }else{
      echo json_encode( array("status" => 0,"message" => "Invalid ID.") );
      exit;
   }
}

// Delete User
if($request == 4){
   $id = 0;

   if(isset($_POST['id'])){
      $id = mysqli_escape_string($con,$_POST['id']);
   }

   // Check id
   $record = mysqli_query($con,"SELECT id FROM users WHERE id=".$id);
   if(mysqli_num_rows($record) > 0){

      mysqli_query($con,"DELETE FROM users WHERE id=".$id);

      echo 1;
      exit;
   }else{
      echo 0;
      exit;
   }
}

6. jQuery

Initialize DataTables

Initialize DataTables on #userTable and assign in userDataTable. Set processing: true, serverSide: true, serverMethod: 'post'. Specify AJAX url with 'ajax' option.

With 'columns' option specifies key names that need to read from AJAX response.

Update User

Define click event on .updateUser class. Read user id from data-id attribute and assign in id variable. Update value of #txt_userid.

Send AJAX POST request to 'ajaxfile.php' file. Pass {request: 2, id: id}, set dataType: 'json'.
On successful callback check if response.status == 1 or not. If equals then read values from response.data and update the value of Bootstrap modal input elements.

Define click event on #btn_save. Read edit id from #txt_userid and assign in id variable. Similarly, read name, email, gender, and city from input elements and assign in variables.

If values are not empty then send AJAX POST request to 'ajaxfile.php' file. Pass {request: 3, id: id,name: name, email: email, gender: gender, city: city} as data. Set dataType: 'json'.

On successful callback check if response.status == 1 or not. If equals then alert(response.message) and reset input elements value.

Reload Datatable by calling userDataTable.ajax.reload() and toggle the #updateModal modal.

Delete User

Define click event on .deleteUser class. Read delete user id from data-id attribute. Display confirm alert message. If deleteConfirm == true then send AJAX POST request to 'ajaxfile.php' file. Pass {request: 4, id: id} as data.

On successful callback alert("Record deleted.") if response == 1 and reload Datatable by calling userDataTable.ajax.reload().

Completed Code

$(document).ready(function(){

  // DataTable
  var userDataTable = $('#userTable').DataTable({
     'processing': true,
     'serverSide': true,
     'serverMethod': 'post',
     'ajax': {
        'url':'ajaxfile.php'
     },
     'columns': [
        { data: 'name' },
        { data: 'email' },
        { data: 'gender' },
        { data: 'city' },
        { data: 'action' },
     ]
  });

  // Update record
  $('#userTable').on('click','.updateUser',function(){
     var id = $(this).data('id');

     $('#txt_userid').val(id);

     // AJAX request
     $.ajax({
        url: 'ajaxfile.php',
        type: 'post',
        data: {request: 2, id: id},
        dataType: 'json',
        success: function(response){
           if(response.status == 1){

             $('#name').val(response.data.name);
             $('#email').val(response.data.email);
             $('#gender').val(response.data.gender);
             $('#city').val(response.data.city);

             userDataTable.ajax.reload();
           }else{
             alert("Invalid ID.");
           }
        }
     });

  });

  // Save user 
  $('#btn_save').click(function(){
     var id = $('#txt_userid').val();

     var name = $('#name').val().trim();
     var email = $('#email').val().trim();
     var gender = $('#gender').val().trim();
     var city = $('#city').val().trim();

     if(name !='' && email != '' && city != ''){

       // AJAX request
       $.ajax({
         url: 'ajaxfile.php',
         type: 'post',
         data: {request: 3, id: id,name: name, email: email, gender: gender, city: city},
         dataType: 'json',
         success: function(response){
            if(response.status == 1){
               alert(response.message);

               // Empty and reset the values
               $('#name','#email','#city').val('');
               $('#gender').val('male');
               $('#txt_userid').val(0);

               // Reload DataTable
               userDataTable.ajax.reload();

               // Close modal
               $('#updateModal').modal('toggle');
            }else{
               alert(response.message);
            }
         }
      });

    }else{
       alert('Please fill all fields.');
    }
  });

  // Delete record
  $('#userTable').on('click','.deleteUser',function(){
     var id = $(this).data('id');

     var deleteConfirm = confirm("Are you sure?");
     if (deleteConfirm == true) {
        // AJAX request
        $.ajax({
          url: 'ajaxfile.php',
          type: 'post',
          data: {request: 4, id: id},
          success: function(response){
             if(response == 1){
                alert("Record deleted.");

                // Reload DataTable
                userDataTable.ajax.reload();
             }else{
                alert("Invalid ID.");
             }
          }
        });
     } 

  });
});




Wednesday, October 21, 2020

jQuery plugin: gentleSelect (Dropdown with multiple columns)

Intro

gentleSelect is a jQuery plugin for transforming select boxes into a skinnable alternative. The selection list can be rendered with multiple columns/rows to present larger datasets in a more manageable format. It recognizes the multiple attribute on select boxes and does the right thing automatically.

Source: http://shawnchin.github.io/jquery-gentleSelect/

Sunday, October 11, 2020

PHP JWT & REST API Authentication Tutorial: Login and Signup

 In this tutorial, we'll learn how to add JWT authentication to our REST API PHP application.

We'll see what JWT is and how it works. We'll also see how to get the authorization header in PHP.

We'll create REST API endpoints for allowing users to login and signup to access protected resources.

What is JWT

JWT stands for JSON Web Token and comprised of user encrypted information that can be used to authenticate users and exchange information between clients and servers.

When building REST API, instead of server sessions commonly used in PHP apps we tokens which are sent with HTTP headers from the server to clients where they are persisted (usually using local storage) then attached to every outgoing request originating from the client to the server. The server checks the token and allow or deny access to the request resource.

RESTful APIs are stateless. This means that requests from clients should contain all the necessary information required to process the request.

If you are building a REST API application using PHP, you are not going to use the $_SESSION variable to save data about the client's session.

This means, we can not access the state of a client (such as login state). In order to solve the issue, the client is responsible for perisiting the state locally and send it to the sever with each request.

Since these important information are now persisted in the client local storage we need to protect it from eyes dropping.

Enter JWTs. A JWT token is simply a JSON object that has information about the user. For example:

{
    "user": "bob",
    "email": "bob@email.com",
    "access_token": "at145451sd451sd4e5r4",
    "expire_at"; "11245454"
}

Since thos token can be tampered with to get access to protected resources. For example, a malicious user can change the previous token as follows to access admin only resources on the server:

{
    "user": "administrator",
    "email": "admin@email.com"
}

To prevent this situation, we JWTs need to be signed by the server. If the token is changed on the client side, the token's signature will no longer be valid and the server will deny access to the requested resource.

How JWT Works

JWT tokens are simply encrypted user's information like identifier, username, email and password.

When users are successfully logged in the server, the latter will produce and send a JWT token back to the client.

This JWT token will be persisted by the client using the browser's local storage or cookies and attached with every outgoing request so if the user requests access to certain protected resources, the token needs to be checked first by the server to allow or deny access.

What is PHP-JWT

php-jwt is a PHP library that allows you to encode and decode JSON Web Tokens (JWT) in PHP, conforming to RFC 7519.

Prerequisites

You must have the following prerequsites to be able to follow this tutorial from scratch:

  • You need PHP 7, Composer and MySQL database system installed on your development environment,
  • You need to have basic knowledge of PHP and SQL.

Creating the MySQL Database and Table(s)

If you have the prerequisites, let's get started by creating the MySQL database. We'll be using the MySQL client installed with the server. Open a terminal and run the following command to invoke the client:

$ mysql -u root -p

You need to enter your MySQL password when prompted.

Next, let's create a database using the following SQL instruction:

mysql> create database db;

Note: Here we assume you have a MySQL user called root. You need to change that to the name of an existing MySQL user.

You can also use phpMyAdmin or any MySQL client you are comfortable with to create the database and SQL tables.

Let's now select the db database and create a users table that will hold the users of our application:

mysql> use db;
mysql> CREATE  TABLE IF NOT EXISTS `Users` (
  `id` INT  AUTO_INCREMENT ,
  `first_name` VARCHAR(150) NOT NULL ,
  `last_name` VARCHAR(150) NOT NULL ,
  `email` VARCHAR(255),
  `password` VARCHAR(255),
  PRIMARY KEY (`id`) );

Creating the Project Directory Structure

Let's create a simple directory strucutre for our project. In your terminal, navigate to your working directory and create a folder for our project:

$ mkdir php-jwt-example
$ cd php-jwt-example
$ mkdir api && cd api
$ mkdir config

We first created the project's directory.

Next, we created an api folder. Inside it, we created a config folder.

Connecting to your MySQL Database in PHP

Navigate to the config folder and create a database.php file with the following code:

<?php
// used to get mysql database connection
class DatabaseService{

    private $db_host = "localhost";
    private $db_name = "mydb";
    private $db_user = "root";
    private $db_password = "";
    private $connection;

    public function getConnection(){

        $this->connection = null;

        try{
            $this->connection = new PDO("mysql:host=" . $this->db_host . ";dbname=" . $this->db_name, $this->db_user, $this->db_password);
        }catch(PDOException $exception){
            echo "Connection failed: " . $exception->getMessage();
        }

        return $this->connection;
    }
}
?>

Installing php-jwt

Let's now proceed to install the php-jwt library using Composer. In your terminal, run the following command from the root of your project's directory:

$ composer require firebase/php-jwt

This will donwload the php-jwt library into a vendor folder.

You can require the php-jwt library to encode and decode JWT tokens using the following code:

<?php 
require "vendor/autoload.php";
use \Firebase\JWT\JWT;

Adding the User Registration API Endpoint

Inside the api folder, create a register.php file and add the following code to create a new user in the MySQL database:

<?php
include_once './config/database.php';

header("Access-Control-Allow-Origin: * ");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

$firstName = '';
$lastName = '';
$email = '';
$password = '';
$conn = null;

$databaseService = new DatabaseService();
$conn = $databaseService->getConnection();

$data = json_decode(file_get_contents("php://input"));

$firstName = $data->first_name;
$lastName = $data->last_name;
$email = $data->email;
$password = $data->password;

$table_name = 'Users';

$query = "INSERT INTO " . $table_name . "
                SET first_name = :firstname,
                    last_name = :lastname,
                    email = :email,
                    password = :password";

$stmt = $conn->prepare($query);

$stmt->bindParam(':firstname', $firstName);
$stmt->bindParam(':lastname', $lastName);
$stmt->bindParam(':email', $email);

$password_hash = password_hash($password, PASSWORD_BCRYPT);

$stmt->bindParam(':password', $password_hash);


if($stmt->execute()){

    http_response_code(200);
    echo json_encode(array("message" => "User was successfully registered."));
}
else{
    http_response_code(400);

    echo json_encode(array("message" => "Unable to register the user."));
}
?>

Adding the User Login API Endpoint

Inside the api folder, create a login.php file and add the following code to check the user credentials and return a JWT token to the client:

<?php
include_once './config/database.php';
require "../vendor/autoload.php";
use \Firebase\JWT\JWT;

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");


$email = '';
$password = '';

$databaseService = new DatabaseService();
$conn = $databaseService->getConnection();



$data = json_decode(file_get_contents("php://input"));

$email = $data->email;
$password = $data->password;

$table_name = 'Users';

$query = "SELECT id, first_name, last_name, password FROM " . $table_name . " WHERE email = ? LIMIT 0,1";

$stmt = $conn->prepare( $query );
$stmt->bindParam(1, $email);
$stmt->execute();
$num = $stmt->rowCount();

if($num > 0){
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    $id = $row['id'];
    $firstname = $row['first_name'];
    $lastname = $row['last_name'];
    $password2 = $row['password'];

    if(password_verify($password, $password2))
    {
        $secret_key = "owt56789"; //add here your secret key
        $issuer_claim = "localhost"; // this can be the servername
        $audience_claim = "myusers"; //your audience
        $issuedat_claim = time(); // issued at
        $notbefore_claim = $issuedat_claim + 10; //not before in seconds
        $expire_claim = $issuedat_claim + 60; // expire time in seconds
        $token = array(
            "iss" => $issuer_claim,
            "aud" => $audience_claim,
            "iat" => $issuedat_claim,
            "nbf" => $notbefore_claim,
            "exp" => $expire_claim,
            "data" => array(
                "id" => $id,
                "firstname" => $firstname,
                "lastname" => $lastname,
                "email" => $email
        ));

        http_response_code(200);

        $jwt = JWT::encode($token, $secret_key);
        echo json_encode(
            array(
                "message" => "Successful login.",
                "jwt" => $jwt,
                "email" => $email,
                "expireAt" => $expire_claim
            ));
    }
    else{

        http_response_code(401);
        echo json_encode(array("message" => "Login failed.", "password" => $password));
    }
}
?>

You can define the data structure of the token as you want i.e (You can add only the user's email or ID or both with any extra information like the user's name) but there are some reserved JWT claims that should be defined properly because they affect the validity of the JWT token, such as:

  • iat – timestamp of token issuing.

  • iss – A string containing the name or identifier of the issuer application. Can be a domain name and can be used to discard tokens from other applications.

  • nbf – Timestamp of when the token should start being considered valid. Should be equal to or greater than iat. In this case, the token will begin to be valid after 10 seconds after being issued

  • exp – Timestamp of when the token should stop to be valid. Needs to be greater than iat and nbf. In our example, the token will expire after 60 seconds of being issued.

These claims are not required, but are useful for determining the validity of a token.

Our JWT payload is inside the data claim, we added the first name, last name, email and user ID from the database. You shouldn't add any sensitive information in the JWT payload.

The JWT::encode() method will transform the PHP array into JSON format and sign the payload then encode the final JWT token that will be sent to the client. In our example, we simply hradcoded the secret key that will be used for signing the JWT payload but in production, you need to make sure you use a secret key with a long, binary string, store it in a configuration file.

We now have two RESTful endpoints for registering and log users in. At this point, you can use a REST client like Postman to intercat with the API.

First, start your PHP server using the following command:

$ php -S 127.0.0.1:8080

A development server will be running from the 127.0.0.1:8080 address.

Let's now, create a user in the database by sending a POST request to the api/register.php endpoint with a JSON body that contains the first_namelast_nameemail and password:

PHP JWT Authentication Example

You should get an 200 HTTP response with a User was successfully registered. message.

Next, you need to send a POST request to the /api/login.php endpoint with a JSON body that contains the email and password used for registering the user:

PHP JWT Authentication Example

You should get a Successful login message with a JWT token.

The JWT token needs to be persisted in your browser's local storage or cookies using JavaScript then attached to each send HTTP request to access a protected resource on your PHP server.

Protecting an API Endpoint Using JWT

Let's now see how we can protected our server endpoints using JWT tokens.

Before accessing an endpoint a JWT token is sent with every request from the client. The server needs to decode the JWT and check if it's valid before allowing access to the endpoint.

Inside the api folder, create a protected.php file and add the following code:

<?php
include_once './config/database.php';
require "../vendor/autoload.php";
use \Firebase\JWT\JWT;

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");


$secret_key = "YOUR_SECRET_KEY";
$jwt = null;
$databaseService = new DatabaseService();
$conn = $databaseService->getConnection();

$data = json_decode(file_get_contents("php://input"));


$authHeader = $_SERVER['HTTP_AUTHORIZATION'];

$arr = explode(" ", $authHeader);


/*echo json_encode(array(
    "message" => "sd" .$arr[1]
));*/

$jwt = $arr[1];

if($jwt){

    try {

        $decoded = JWT::decode($jwt, $secret_key, array('HS256'));

        // Access is granted. Add code of the operation here 

        echo json_encode(array(
            "message" => "Access granted:",
            "error" => $e->getMessage()
        ));

    }catch (Exception $e){

    http_response_code(401);

    echo json_encode(array(
        "message" => "Access denied.",
        "error" => $e->getMessage()
    ));
}

}
?>

Note: We assume that the client sends the JWT token inside an HTTP Authorization header in the JWT <token> or Bearer <token> formats. You can also choose to include the token as a parameter in the request URL or as part of data payload sent from the client if you don't want to deal with HTTP headers.

You can now send a POST request with an Authorization header in the following formats:

JWT <YOUR_JWT_TOKEN_HERE> 

Or also using the bearer format:

Bearer <YOUR_JWT_TOKEN_HERE>

PHP JWT

Conclusion

In this tutorial, we've seen how to implement REST API JWT authentication in PHP and MySQL.

Credit & Source: https://www.techiediaries.com/php-jwt-authentication-tutorial/?fbclid=IwAR27DtqFhlZxec5lJV4Y0WOwUlFdFU9pinfQ7LZ8PjotI6zSXgyGp1ZlWcs


Friday, October 2, 2020

How to forbidden Right Click, ctrl+c, ctrl+u, and F12 with javascript

 // To disable right click

document.addEventListener('contextmenu', event => event.preventDefault());

// To disable F12 options

document.onkeypress = function (event) {

event = (event || window.event);

if (event.keyCode == 123) {

return false;

}

}

document.onmousedown = function (event) {

event = (event || window.event);

if (event.keyCode == 123) {

return false;

}

}

document.onkeydown = function (event) {

event = (event || window.event);

if (event.keyCode == 123) {

return false;

}

}

// To To Disable ctrl+c, ctrl+u

jQuery(document).ready(function($){

$(document).keydown(function(event) {

var pressedKey = String.fromCharCode(event.keyCode).toLowerCase();

if (event.ctrlKey && (pressedKey == "c" || pressedKey == "u")) {

alert('Sorry, This Functionality Has Been Disabled!');

//disable key press porcessing

return false;

}

});

});

Thursday, July 2, 2020

Replacing Background Colors in Cells

It's fairly obvious that you can change the background colors of any cells manually, so there is no need to go into that option for making the changes. What you need to do is use a simple tool, such as the Find and Replace tool, to make the color changes. Follow these steps:
  1. Press Ctrl+H to display the Replace tab of the Find and Replace dialog box.
  2. Expand the dialog box by clicking the Options button. (See Figure 1.)
  3. Figure 1. The Replace tab of the Find and Replace dialog box.
  4. Click the Format button at the right side of the Find What box. Excel displays the Find Format dialog box.
  5. Make sure the Fill tab is selected. (See Figure 2.)
  6. Figure 2. The Fill tab of the Find Format dialog box.
  7. Use the controls in the dialog box to specify the background color you want to replace.
  8. Click OK.
  9. Click the Format button at the right side of the Replace With box. Excel displays the Replace Format dialog box.
  10. Make sure the Fill tab is selected.
  11. Use the controls in the dialog box to specify the background color you used when changing the cells.
  12. Click OK.
  13. Click Replace All.
If you find yourself needing to make the same color changes over and over (for instance, always changing from red to blue), then you may be interested in using a macro to do the changes. The following example could be assigned to a shortcut key or added to the Quick Access Toolbar so you can use it quickly:
Sub ChangeColor()
    Dim rCell As Range
    If Selection.Cells.Count = 1 Then
        MsgBox "Select the range to be processed."
        Exit Sub
    End If
    For Each rCell In Selection
        If rCell.Interior.Color = RGB(255, 0, 0) Then  'red
            rCell.Interior.Color = RGB(0, 0, 255)      'blue
        End If
    Next rCell
End Sub

Friday, April 3, 2020

Drawing rotated text on a HTML5 canvas

Posting this in an effort to help others with similar problems. I solved this issue with a five step approach -- save the context, translate the context, rotate the context, draw the text, then restore the context to its saved state.
I think of translations and transforms to the context as manipulating the coordinate grid overlaid on the canvas. By default the origin (0,0) starts in the upper left hand corner of the canvas. X increases from left to right, Y increases from top to bottom. If you make an "L" w/ your index finger and thumb on your left hand and hold it out in front of you with your thumb down, your thumb would point in the direction of increasing Y and your index finger would point in the direction of increasing X. I know it's elementary, but I find it helpful when thinking about translations and rotations. Here's why:
When you translate the context, you move the origin of the coordinate grid to a new location on the canvas. When you rotate the context, think of rotating the "L" you made with your left hand in a clockwise direction the amount indicated by the angle you specify in radians about the origin. When you strokeText or fillText, specify your coordinates in relation to the newly aligned axes. To orient your text so it's readable from bottom to top, you would translate to a position below where you want to start your labels, rotate by -90 degrees and fill or strokeText, offsetting each label along the rotated x axis. Something like this should work:
 context.save();
 context.translate(newx, newy);
 context.rotate(-Math.PI/2);
 context.textAlign = "center";
 context.fillText("Your Label Here", labelXposition, 0);
 context.restore();
.restore() resets the context back to the state it had when you called .save() -- handy for returning things back to "normal".

Tuesday, March 17, 2020

How to add rowspan in table column if values is the same using jQuery

By using jQUery

<table border=1 id="myTable">
        <tr>
            <td>A</td>
            <td>1</td>
        </tr>
        <tr>
            <td>A</td>
            <td>2</td>
        </tr>
        <tr>
            <td>b</td>
            <td>1</td>
        </tr>
        <tr>
            <td>c</td>
            <td>1</td>
        </tr>
        <tr>
            <td>c</td>
            <td>1</td>
        </tr>
    </table>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

<script>
    $(document).ready(function() {
       var span = 1;
       var prevTD = "";
       var prevTDVal = "";
       $("#myTable tr td:first-child").each(function() { //for each first td in every tr
          var $this = $(this);
          if ($this.text() == prevTDVal) { // check value of previous td text
             span++;
             if (prevTD != "") {
                prevTD.attr("rowspan", span); // add attribute to previous td
                $this.remove(); // remove current td
             }
          } else {
             prevTD     = $this; // store current td 
             prevTDVal  = $this.text();
             span       = 1;
          }
       });
    });
</script>

How to change the PHP version for subfolders or subdomains

  How to change the PHP version for subfolders or subdomains Setting a specific PHP version for a specific websites, subfolders or subdomain...