Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 28, 2021 11:45 pm GMT

JSON Web Tokens without Firebase JWT

I have created a few tutorials on how to use Firebase JWT to create and use JSON Web Tokens, but I decided to try to do it without a framework, using just PHP. In this article, you can see how I created my own simple JWT generator.

View This On YouTube

Creating Our Class

class JWT {    private $headers;    private $secret;    public function __construct()    {        $this->headers = [            'alg' => 'HS256', // we are using a SHA256 algorithm            'typ' => 'JWT', // JWT type            'iss' => 'jwt.local', // token issuer            'aud' => 'example.com' // token audience        ];        $this->secret = 'thisIsASecret';    }}

Generate A Token

Within this class, we will create our generate function. this function will generate our token to be used against our validator.

public function generate(array $payload): string{    $headers = $this->encode(json_encode($this->headers)); // encode headers    $payload["exp"] = time() + 60; // add expiration to payload    $payload = $this->encode(json_encode($payload)); // encode payload    $signature = hash_hmac('SHA256', "$headers.$payload", $this->secret, true); // create SHA256 signature    $signature = $this->encode($signature); // encode signature    return "$headers.$payload.$signature";}

Within our generate function, we reference a encode function. This function will simply base64 encode our strings to be used by the token.

private function encode(string $str): string{    return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); // base64 encode string}

Validate Our Token

In this function, we take the generated token, and validate the strings, the encoding, and finally the time. I have it set for 1 minute so the token will expire after 1 minute to ensure it is used for a purpose.

public function is_valid(string $jwt): bool{    $token = explode('.', $jwt); // explode token based on JWT breaks    if (!isset($token[1]) && !isset($token[2])) {        return false; // fails if the header and payload is not set    }    $headers = base64_decode($token[0]); // decode header, create variable    $payload = base64_decode($token[1]); // decode payload, create variable    $clientSignature = $token[2]; // create variable for signature    if (!json_decode($payload)) {        return false; // fails if payload does not decode    }    if ((json_decode($payload)->exp - time()) < 0) {        return false; // fails if expiration is greater than 0, setup for 1 minute    }    if (isset(json_decode($payload)->iss)) {        if (json_decode($headers)->iss != json_decode($payload)->iss) {            return false; // fails if issuers are not the same        }    } else {        return false; // fails if issuer is not set     }    if (isset(json_decode($payload)->aud)) {        if (json_decode($headers)->aud != json_decode($payload)->aud) {            return false; // fails if audiences are not the same        }    } else {        return false; // fails if audience is not set    }    $base64_header = $this->encode($headers);    $base64_payload = $this->encode($payload);    $signature = hash_hmac('SHA256', $base64_header . "." . $base64_payload, $this->secret, true);    $base64_signature = $this->encode($signature);    return ($base64_signature === $clientSignature);}

Putting It All Together

class JWT{    private $headers;    private $secret;    public function __construct()    {        $this->headers = [            'alg' => 'HS256', // we are using a SHA256 algorithm            'typ' => 'JWT', // JWT type            'iss' => 'jwt.local', // token issuer            'aud' => 'example.com' // token audience        ];        $this->secret = 'thisIsASecret'; // change this to your secret code    }    public function generate(array $payload): string    {        $headers = $this->encode(json_encode($this->headers)); // encode headers        $payload["exp"] = time() + 60; // add expiration to payload        $payload = $this->encode(json_encode($payload)); // encode payload        $signature = hash_hmac('SHA256', "$headers.$payload", $this->secret, true); // create SHA256 signature        $signature = $this->encode($signature); // encode signature        return "$headers.$payload.$signature";    }    private function encode(string $str): string    {        return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); // base64 encode string    }    public function is_valid(string $jwt): bool    {        $token = explode('.', $jwt); // explode token based on JWT breaks        if (!isset($token[1]) && !isset($token[2])) {            return false; // fails if the header and payload is not set        }        $headers = base64_decode($token[0]); // decode header, create variable        $payload = base64_decode($token[1]); // decode payload, create variable        $clientSignature = $token[2]; // create variable for signature        if (!json_decode($payload)) {            return false; // fails if payload does not decode        }        if ((json_decode($payload)->exp - time()) < 0) {            return false; // fails if expiration is greater than 0, setup for 1 minute        }        if (isset(json_decode($payload)->iss)) {            if (json_decode($headers)->iss != json_decode($payload)->iss) {                return false; // fails if issuers are not the same            }        } else {            return false; // fails if issuer is not set         }        if (isset(json_decode($payload)->aud)) {            if (json_decode($headers)->aud != json_decode($payload)->aud) {                return false; // fails if audiences are not the same            }        } else {            return false; // fails if audience is not set        }        $base64_header = $this->encode($headers);        $base64_payload = $this->encode($payload);        $signature = hash_hmac('SHA256', $base64_header . "." . $base64_payload, $this->secret, true);        $base64_signature = $this->encode($signature);        return ($base64_signature === $clientSignature);    }}

Conclusion

It is a simple project, but works as intended. I have used Firebase JWT in the past but sometimes you just need a simple solution without having to import and entire library. I hope this helps for your next small project. You can download the class on my GitHub or subscribe on YouTube for more tutorials.


Original Link: https://dev.to/thedevdrawer/json-web-tokens-without-firebase-jwt-3mop

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To