3

How to generate JWT token in php using with the following parameters Subject, Issuer, Expiry time and payload in the < PAYLOAD > tag.

  • Id can be any random number of any length.
  • subject is TestService
  • Issuer is Baguma Inc
  • Expiry Time will be 30 sec from current time(ideally ).
  • Payload is the request from Third Party
  • SigningKEY is fcvxcnfrhrtghkfghgwerikdf
  • Signature algorithm will be HS512.

Sample request from Third Party is shown below

<COMMAND><TYPE>REQUEST</TYPE><INTERFACE>TESTACCOUNT</INTERFACE> <REQUESTID>123</REQUESTID></COMMAND

Baguma
  • 173
  • 1
  • 2
  • 15

3 Answers3

8

Your answer got me started. Here's the working code I went with (albeit generalized from your specific case). Thanks for getting me started!

function gen_jwt():String{
    $signing_key = "changeme";
    $header = [ 
        "alg" => "HS512", 
        "typ" => "JWT" 
    ];
    $header = base64_url_encode(json_encode($header));
    $payload =  [
        "exp" => 0,
    ];
    $payload = base64_url_encode(json_encode($payload));
    $signature = base64_url_encode(hash_hmac('sha512', "$header.$payload", $signing_key, true));
    $jwt = "$header.$payload.$signature";
    return $jwt;    
}

/**
 * per https://stackoverflow.com/questions/2040240/php-function-to-generate-v4-uuid/15875555#15875555
 */
function base64_url_encode($text):String{
    return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($text));
}
cloudsurfin
  • 2,467
  • 2
  • 25
  • 29
  • 2
    No need for extra external libraries. Thanks a lot! JWT validates fine @ https://jwt.io/ – Cagy79 Sep 08 '22 at 20:22
  • Another Tip: For my target API I needed to change the algo & hmac to HS256 + sha256 to avoid an "Algorithm not allowed" error. – Cagy79 Sep 08 '22 at 20:39
  • For decoding use `function base64_url_decode($text) { return base64_decode(str_replace(['-', '_'], ['+', '/'], $text)); } ` – Jurakin Jun 19 '23 at 06:48
2

With the help of an article from DZone Security, I managed to generate a JWT token by doing the following

  1. Define the base64UrlEncode function which replaces + with -, / with _ and = with ''.
function base64UrlEncode($text)
{
    return str_replace(
        ['+', '/', '='],
        ['-', '_', ''],
        base64_encode($text)
    );
}

  1. Encode the headers using base64UrlEncode
$headers = [ "alg" => "HS512"];

$headers_encoded = $this->base64UrlEncode(json_encode($headers));
  1. Encode the Payload using Base64 URL encode as well
$issuedAt = time();

    $payload =  [
        "id" =>$this->gen_uuid(), //   .setId(UUID.randomUUID().toString())
        "sub"=> "TestService", //Subject
        "exp"=> $issuedAt+30,
        "iss"=> "Baguma Inc",  //issuer
        "iat"=> $issuedAt,  //issued at
        "PAYLOAD"=> "<COMMAND><TYPE>REQUEST</TYPE><INTERFACE>TESTACCOUNT</INTERFACE> <REQUESTID>123</REQUESTID></COMMAND"];

      $payload_encoded = $this->base64UrlEncode(json_encode($payload));
  1. Using the Key/secret build the signature
$key = "fcvxcnfrhrtghkfghgwerikdf";  
$signature = hash_hmac('sha512',"$headers_encoded.$payload_encoded",$key,true);

5 Encode the signature

$signature_encoded = $this->base64UrlEncode($signature);
  1. Build and return the token
$token = "$headers_encoded.$payload_encoded.$signature_encoded";
mik3fly-4steri5k
  • 712
  • 3
  • 15
  • 32
Baguma
  • 173
  • 1
  • 2
  • 15
0

You can use the PHP Library like Firebase JWT https://github.com/firebase/php-jwt