Hey developers , in this article i’m going to demonstrate you how you can implement JWT authentication with php API’s . First of all let’s talk about some basic questions .

What is JWT ?

JSON Web Token (JWT) is a very secure way for authenticating users on a web app. JWT is comprised of user encrypted information that can be used to authenticate users and exchange information between clients and servers .

Mainly JWT contains three parts

  1. Header – contains the type of algo used in token .
  2. Payload – contains the information of user .
  3. Signature – This is digitally signed part using the algorithm specified in header. This part is combination of header , payload and secret key stored in server .
jwt with php - bepractical.tech
Parts of JWT

Why use JWT ?

As we all know that REST API’s are stateless and commonly for authentication we use tokens which are sent with HTTP headers from server to client where they are persisted (in cookies or local storage) . And then that token is attached to every single request sent from client to server , server validate the token and allocate resources to client .

This means every request from client for RESTful API’s contains all the necessary data which are required for authentication . Since these important information are persisted in local storage we need to protect it from eyes dropping .

Here JWT enters the room , it is a simple JSON object which includes all the necessary information about the authenticated user .

{
    "user_name": "BePractical",
    "user_email": "[email protected]",
    "user_token": "ThereWeGo",
    "expire_at"; "76543897"
}

Since these information can be tempered , let’s say a malicious user modified the information and sent the modified token with request . In this case the signature of recieved token will no longer be valid and thus server restrict access to resources .

How JWT works ?

So , now let’s talk about working of JWT . Let’s say we have developed an API with endpoint /login and /resources . Now what user will do is , he will make a request with his email and password to /login and he will recieve a signed JWT token generated by server if the credentials are valid .

Now this token will be stored in cookies or in HTTP_AUTHORIZATION header , so that token can be send with every request from client side to /resource endpoint .

Now when server recieve a token from client side on /resource endpoint , it will decode the hashed part before first period (.) and hashed part before second period (.) of recieved token .

for example let’s say we have the below token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
tAcuqk2q92tBYonobCb-58UbewuIwYDc9t8H8arebEM

it will decode the eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 part and eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ part , then it will encode it again with the secret key stored on server using the algorithm specified in header and will match the encoded version with the hashed part before third period (.) of recieved token .

If it matches it means user is authenticaed thus allowing the access , otherwise user is unauthenticated and will deny the access .

How to implement JWT with PHP ?

Prerequisites

  1. PHP
  2. Composer

First of all install the php-jwt package with the follow command

composer require Firebase/php-jwt

Making a login endpoint

After this make a login.php file and write the below code in it

define("SECRET_KEY", "ThereWeGoAgain");

require_once('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");

In the above code we are defining a secret_key i.e., ThereWeGoAgain ( you can choose any other key ) . Then we are including JWT file and allowing some necessary headers to accept in our login.php file .

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

if the recieved credentials are valid then we can generate a token

$issuedAt   = new DateTimeImmutable();
$expire     = $issuedAt->modify('+6 minutes')->getTimestamp();      // Add 60 seconds
$serverName = "localhost";
$username   = $person['username'];

$data = [
     'iat'  => $issuedAt->getTimestamp(),         // Issued at: time when the token was generated
     'iss'  => $serverName,                       // Issuer
     'username' => $username,                     // User name
 ];

echo JWT::encode(
   $data,
   SECRET_KEY,
   'HS512' //algo for signing
);

JWT::encode() method is used to generate a token and sending it as a response

The user will recieve a response of JWT after providing valid credentials to login.php endpoint.

Making a resource endpoint

Now make a file named resource.php and write the below code in it .

require_once('vendor/autoload.php');
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

define("SECRET_KEY", "ThereWeGoAgain");

if (! preg_match('/Bearer\s(\S+)/', $_SERVER['HTTP_AUTHORIZATION'], $matches)) {
    header('HTTP/1.0 400 Bad Request');
    echo 'Token not found in request';
    exit;
}

$jwt = $matches[1];
if (! $jwt) {
    // No token was able to be extracted from the authorization header
    header('HTTP/1.0 400 Bad Request');
    exit;
}

In the above code we are checking whether the request has a JWT token in it or not . In this example we are assuming that JWT token is set in Bearer HTTP_AUTHORIZATION header as Bearer <token>. If there is JWT found then we are responding with Bad Request header .

try {

    JWT::decode($jwt, new key(SECRET_KEY, 'HS512'));

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

    echo json_encode(array(
        "message" => "Access granted:"
    ));

}catch (Exception $e){

    http_response_code(401);

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

And if the token found and is valid then we are responding with a message of Access Granted else token found and is invalid then we are responding with Access Denied message .

Testing the API

You can use POSTMAN or if using VS Code try using Thunder Client extension to test the API’s .

checkout here for more clearance on working of JWT .

So that’s all for this aritcle guys . You can

Follow me on Linkedin : Anand Raj

Follow our Linkedin page : Be Practical

Join Our Telegram community over here

Checkout our latest course on udemy

battery status with javascript - bepractical.tech

Chat Application with Javascript , Jquery and Firebase

Rating : 4.8

2.5 Total Hours | 27 Lectures | Intermediate

Next Article : Easiest way to connect database with javascript : 3 simple steps

Thanks for reading ✌