Verify Access_Token JWT with jose-php

Note: I read this topic and went through the Laravel quick start: Laravel API. Should I manually verify access token's signature?

Hello everyone,

I was seeking a dynamic jwt verification solution for PHP, I came across jose-php which allowed me to:

convert JWKS to PEM => Decode JWT => verify Data against PEM

I will then apply other custom middlewares:

  • Expiration check on the token
  • Validation of Scope & Audience

Here is a sample code of verification middleware with the dummy data:

# public key retrieved from JWKS endpoint
$components = array(
    'kty' => 'RSA',
    'e' => 'AQAB',
    'n' => 'x9vNhcvSrxjsegZAAo4OEuo...'

$public_key= JOSE_JWK::decode($components);

$jwt_string = 'eyJ...'; // Access_token
$jws = JOSE_JWT::decode($jwt_string);
$result = $jws->verify($public_key, 'RS256');

I am currently getting undefined on $result, Which I am also looking into it.

My question is, is this a valid way or I am exposing a vulnerability by doing such a thing, and if there is any other potential better way that does not use the Client SDKs?

Just an update on the process, I switched to firebase/php-jwt as it is more convenient and straightforward to use and it was fairly easier to go quickly through its code and it does not return undefined anymore. Now the middleware code for validation looks like below:

$jwks = ['keys' => [[], []]; 

// JWK::parseKeySet($jwks) returns an associative array of **kid** to private

// key. Pass this as the second parameter to JWT::decode. 
// Instead of RS256 use your own algo
// $data can return error so wrap it in try catch and do as you desire afterward
$data= (array) JWT::decode("YOUR_ACCESS_TOKEN", JWK::parseKeySet($jwks), ['RS256', 'RS256']);

For those who are willing to test a sample encoding and decoding process, feel free to use the private key and public key below: (Credit to firebase documentation with a bit of tweaking on my side to convert it to a simple Laravel controller)


namespace App\Http\Controllers;

use Illuminate\Http\Request;

use \Firebase\JWT\JWT;

use \Firebase\JWT\JWK;

use Illuminate\Support\Facades\Http;

class JWTValidation extends Controller


    public function bundle(){


        $privateKey = <<<EOD

        -----BEGIN RSA PRIVATE KEY-----














        -----END RSA PRIVATE KEY-----


        $publicKey = <<<EOD

        -----BEGIN PUBLIC KEY-----





        -----END PUBLIC KEY-----



        $payload = array(

            "iss" => "",

            "aud" => "",

            "iat" => 1356999524,

            "nbf" => 1357000000



        $jwt = JWT::encode($payload, $privateKey, 'RS256');

        //echo "Encode:\n" . print_r($jwt, true) . "\n";


        $decoded = JWT::decode($jwt, $publicKey, array('RS256'));



         NOTE: This will now be an object instead of an associative array. To get

         an associative array, you will need to cast it as such:



        $decoded_array = (array) $decoded;

        return response()->json(['jwt' => $jwt, 'decoded' => $decoded]);

        //echo "Decode:\n" . print_r($decoded_array, true) . "\n";


Now back to my first question again :slight_smile:

In case that I validate the key with the help of this library as the first piece of the code, am I exposing any vulnerability? or will it be a time-consuming task in long run to maintain a custom verification flow like this?