Coder Social home page Coder Social logo

php-jwt's Introduction

Build Status Latest Stable Version Total Downloads License

PHP-JWT

A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to RFC 7519.

Installation

Use composer to manage your dependencies and download PHP-JWT:

composer require firebase/php-jwt

Optionally, install the paragonie/sodium_compat package from composer if your php env does not have libsodium installed:

composer require paragonie/sodium_compat

Example

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = 'example_key';
$payload = [
    'iss' => 'http://example.org',
    'aud' => 'http://example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

/**
 * IMPORTANT:
 * You must specify supported algorithms for your application. See
 * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40
 * for a list of spec-compliant algorithms.
 */
$jwt = JWT::encode($payload, $key, 'HS256');
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
print_r($decoded);

// Pass a stdClass in as the third parameter to get the decoded header values
$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers = new stdClass());
print_r($headers);

/*
 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;

/**
 * You can add a leeway to account for when there is a clock skew times between
 * the signing and verifying servers. It is recommended that this leeway should
 * not be bigger than a few minutes.
 *
 * Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef
 */
JWT::$leeway = 60; // $leeway in seconds
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));

Example encode/decode headers

Decoding the JWT headers without verifying the JWT first is NOT recommended, and is not supported by this library. This is because without verifying the JWT, the header values could have been tampered with. Any value pulled from an unverified header should be treated as if it could be any string sent in from an attacker. If this is something you still want to do in your application for whatever reason, it's possible to decode the header values manually simply by calling json_decode and base64_decode on the JWT header part:

use Firebase\JWT\JWT;

$key = 'example_key';
$payload = [
    'iss' => 'http://example.org',
    'aud' => 'http://example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$headers = [
    'x-forwarded-for' => 'www.google.com'
];

// Encode headers in the JWT string
$jwt = JWT::encode($payload, $key, 'HS256', null, $headers);

// Decode headers from the JWT string WITHOUT validation
// **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified.
// These headers could be any value sent by an attacker.
list($headersB64, $payloadB64, $sig) = explode('.', $jwt);
$decoded = json_decode(base64_decode($headersB64), true);

print_r($decoded);

Example with RS256 (openssl)

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuzWHNM5f+amCjQztc5QTfJfzCC5J4nuW+L/aOxZ4f8J3Frew
M2c/dufrnmedsApb0By7WhaHlcqCh/ScAPyJhzkPYLae7bTVro3hok0zDITR8F6S
JGL42JAEUk+ILkPI+DONM0+3vzk6Kvfe548tu4czCuqU8BGVOlnp6IqBHhAswNMM
78pos/2z0CjPM4tbeXqSTTbNkXRboxjU29vSopcT51koWOgiTf3C7nJUoMWZHZI5
HqnIhPAG9yv8HAgNk6CMk2CadVHDo4IxjxTzTTqo1SCSH2pooJl9O8at6kkRYsrZ
WwsKlOFE2LUce7ObnXsYihStBUDoeBQlGG/BwQIDAQABAoIBAFtGaOqNKGwggn9k
6yzr6GhZ6Wt2rh1Xpq8XUz514UBhPxD7dFRLpbzCrLVpzY80LbmVGJ9+1pJozyWc
VKeCeUdNwbqkr240Oe7GTFmGjDoxU+5/HX/SJYPpC8JZ9oqgEA87iz+WQX9hVoP2
oF6EB4ckDvXmk8FMwVZW2l2/kd5mrEVbDaXKxhvUDf52iVD+sGIlTif7mBgR99/b
c3qiCnxCMmfYUnT2eh7Vv2LhCR/G9S6C3R4lA71rEyiU3KgsGfg0d82/XWXbegJW
h3QbWNtQLxTuIvLq5aAryV3PfaHlPgdgK0ft6ocU2de2FagFka3nfVEyC7IUsNTK
bq6nhAECgYEA7d/0DPOIaItl/8BWKyCuAHMss47j0wlGbBSHdJIiS55akMvnAG0M
39y22Qqfzh1at9kBFeYeFIIU82ZLF3xOcE3z6pJZ4Dyvx4BYdXH77odo9uVK9s1l
3T3BlMcqd1hvZLMS7dviyH79jZo4CXSHiKzc7pQ2YfK5eKxKqONeXuECgYEAyXlG
vonaus/YTb1IBei9HwaccnQ/1HRn6MvfDjb7JJDIBhNClGPt6xRlzBbSZ73c2QEC
6Fu9h36K/HZ2qcLd2bXiNyhIV7b6tVKk+0Psoj0dL9EbhsD1OsmE1nTPyAc9XZbb
OPYxy+dpBCUA8/1U9+uiFoCa7mIbWcSQ+39gHuECgYAz82pQfct30aH4JiBrkNqP
nJfRq05UY70uk5k1u0ikLTRoVS/hJu/d4E1Kv4hBMqYCavFSwAwnvHUo51lVCr/y
xQOVYlsgnwBg2MX4+GjmIkqpSVCC8D7j/73MaWb746OIYZervQ8dbKahi2HbpsiG
8AHcVSA/agxZr38qvWV54QKBgCD5TlDE8x18AuTGQ9FjxAAd7uD0kbXNz2vUYg9L
hFL5tyL3aAAtUrUUw4xhd9IuysRhW/53dU+FsG2dXdJu6CxHjlyEpUJl2iZu/j15
YnMzGWHIEX8+eWRDsw/+Ujtko/B7TinGcWPz3cYl4EAOiCeDUyXnqnO1btCEUU44
DJ1BAoGBAJuPD27ErTSVtId90+M4zFPNibFP50KprVdc8CR37BE7r8vuGgNYXmnI
RLnGP9p3pVgFCktORuYS2J/6t84I3+A17nEoB4xvhTLeAinAW/uTQOUmNicOP4Ek
2MsLL2kHgL8bLTmvXV4FX+PXphrDKg1XxzOYn0otuoqdAQrkK4og
-----END RSA PRIVATE KEY-----
EOD;

$publicKey = <<<EOD
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzWHNM5f+amCjQztc5QT
fJfzCC5J4nuW+L/aOxZ4f8J3FrewM2c/dufrnmedsApb0By7WhaHlcqCh/ScAPyJ
hzkPYLae7bTVro3hok0zDITR8F6SJGL42JAEUk+ILkPI+DONM0+3vzk6Kvfe548t
u4czCuqU8BGVOlnp6IqBHhAswNMM78pos/2z0CjPM4tbeXqSTTbNkXRboxjU29vS
opcT51koWOgiTf3C7nJUoMWZHZI5HqnIhPAG9yv8HAgNk6CMk2CadVHDo4IxjxTz
TTqo1SCSH2pooJl9O8at6kkRYsrZWwsKlOFE2LUce7ObnXsYihStBUDoeBQlGG/B
wQIDAQAB
-----END PUBLIC KEY-----
EOD;

$payload = [
    'iss' => 'example.org',
    'aud' => 'example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$jwt = JWT::encode($payload, $privateKey, 'RS256');
echo "Encode:\n" . print_r($jwt, true) . "\n";

$decoded = JWT::decode($jwt, new Key($publicKey, '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;
echo "Decode:\n" . print_r($decoded_array, true) . "\n";

Example with a passphrase

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

// Your passphrase
$passphrase = '[YOUR_PASSPHRASE]';

// Your private key file with passphrase
// Can be generated with "ssh-keygen -t rsa -m pem"
$privateKeyFile = '/path/to/key-with-passphrase.pem';

// Create a private key of type "resource"
$privateKey = openssl_pkey_get_private(
    file_get_contents($privateKeyFile),
    $passphrase
);

$payload = [
    'iss' => 'example.org',
    'aud' => 'example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$jwt = JWT::encode($payload, $privateKey, 'RS256');
echo "Encode:\n" . print_r($jwt, true) . "\n";

// Get public key from the private key, or pull from from a file.
$publicKey = openssl_pkey_get_details($privateKey)['key'];

$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256'));
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";

Example with EdDSA (libsodium and Ed25519 signature)

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

// Public and private keys are expected to be Base64 encoded. The last
// non-empty line is used so that keys can be generated with
// sodium_crypto_sign_keypair(). The secret keys generated by other tools may
// need to be adjusted to match the input expected by libsodium.

$keyPair = sodium_crypto_sign_keypair();

$privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair));

$publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));

$payload = [
    'iss' => 'example.org',
    'aud' => 'example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$jwt = JWT::encode($payload, $privateKey, 'EdDSA');
echo "Encode:\n" . print_r($jwt, true) . "\n";

$decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA'));
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";

Example with multiple keys

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

// Example RSA keys from previous example
// $privateKey1 = '...';
// $publicKey1 = '...';

// Example EdDSA keys from previous example
// $privateKey2 = '...';
// $publicKey2 = '...';

$payload = [
    'iss' => 'example.org',
    'aud' => 'example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$jwt1 = JWT::encode($payload, $privateKey1, 'RS256', 'kid1');
$jwt2 = JWT::encode($payload, $privateKey2, 'EdDSA', 'kid2');
echo "Encode 1:\n" . print_r($jwt1, true) . "\n";
echo "Encode 2:\n" . print_r($jwt2, true) . "\n";

$keys = [
    'kid1' => new Key($publicKey1, 'RS256'),
    'kid2' => new Key($publicKey2, 'EdDSA'),
];

$decoded1 = JWT::decode($jwt1, $keys);
$decoded2 = JWT::decode($jwt2, $keys);

echo "Decode 1:\n" . print_r((array) $decoded1, true) . "\n";
echo "Decode 2:\n" . print_r((array) $decoded2, true) . "\n";

Using JWKs

use Firebase\JWT\JWK;
use Firebase\JWT\JWT;

// Set of keys. The "keys" key is required. For example, the JSON response to
// this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
$jwks = ['keys' => []];

// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
// objects. Pass this as the second parameter to JWT::decode.
JWT::decode($payload, JWK::parseKeySet($jwks));

Using Cached Key Sets

The CachedKeySet class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI. This has the following advantages:

  1. The results are cached for performance.
  2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation.
  3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second.
use Firebase\JWT\CachedKeySet;
use Firebase\JWT\JWT;

// The URI for the JWKS you wish to cache the results from
$jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk';

// Create an HTTP client (can be any PSR-7 compatible HTTP client)
$httpClient = new GuzzleHttp\Client();

// Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory)
$httpFactory = new GuzzleHttp\Psr\HttpFactory();

// Create a cache item pool (can be any PSR-6 compatible cache item pool)
$cacheItemPool = Phpfastcache\CacheManager::getInstance('files');

$keySet = new CachedKeySet(
    $jwksUri,
    $httpClient,
    $httpFactory,
    $cacheItemPool,
    null, // $expiresAfter int seconds to set the JWKS to expire
    true  // $rateLimit    true to enable rate limit of 10 RPS on lookup of invalid keys
);

$jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above
$decoded = JWT::decode($jwt, $keySet);

Miscellaneous

Exception Handling

When a call to JWT::decode is invalid, it will throw one of the following exceptions:

use Firebase\JWT\JWT;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
use DomainException;
use InvalidArgumentException;
use UnexpectedValueException;

try {
    $decoded = JWT::decode($payload, $keys);
} catch (InvalidArgumentException $e) {
    // provided key/key-array is empty or malformed.
} catch (DomainException $e) {
    // provided algorithm is unsupported OR
    // provided key is invalid OR
    // unknown error thrown in openSSL or libsodium OR
    // libsodium is required but not available.
} catch (SignatureInvalidException $e) {
    // provided JWT signature verification failed.
} catch (BeforeValidException $e) {
    // provided JWT is trying to be used before "nbf" claim OR
    // provided JWT is trying to be used before "iat" claim.
} catch (ExpiredException $e) {
    // provided JWT is trying to be used after "exp" claim.
} catch (UnexpectedValueException $e) {
    // provided JWT is malformed OR
    // provided JWT is missing an algorithm / using an unsupported algorithm OR
    // provided JWT algorithm does not match provided key OR
    // provided key ID in key/key-array is empty or invalid.
}

All exceptions in the Firebase\JWT namespace extend UnexpectedValueException, and can be simplified like this:

use Firebase\JWT\JWT;
use UnexpectedValueException;
try {
    $decoded = JWT::decode($payload, $keys);
} catch (LogicException $e) {
    // errors having to do with environmental setup or malformed JWT Keys
} catch (UnexpectedValueException $e) {
    // errors having to do with JWT signature and claims
}

Casting to array

The return value of JWT::decode is the generic PHP object stdClass. If you'd like to handle with arrays instead, you can do the following:

// return type is stdClass
$decoded = JWT::decode($payload, $keys);

// cast to array
$decoded = json_decode(json_encode($decoded), true);

Tests

Run the tests using phpunit:

$ pear install PHPUnit
$ phpunit --configuration phpunit.xml.dist
PHPUnit 3.7.10 by Sebastian Bergmann.
.....
Time: 0 seconds, Memory: 2.50Mb
OK (5 tests, 5 assertions)

New Lines in private keys

If your private key contains \n characters, be sure to wrap it in double quotes "" and not single quotes '' in order to properly interpret the escaped characters.

License

3-Clause BSD.

php-jwt's People

Contributors

4026 avatar ajupazhamayil avatar akeeman avatar anantn avatar beamerblvd avatar bshaffer avatar croensch avatar hywak avatar jlesueur avatar josephmcdermott avatar kpn13 avatar krisell avatar luciferous avatar makstech avatar mcocaro avatar nimedia avatar peter279k avatar petrkotek avatar phansys avatar phil-davis avatar ppaulis avatar redian avatar release-please[bot] avatar robertdimarco avatar romainmenke avatar sarciszewski avatar scrummitch avatar sjones608 avatar stampycode avatar vishwarajanand avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-jwt's Issues

Wrong number of segments

hi .
i face with this issue when i trying to decode token that send from retrofit from android in php.
but when i use Firefox rest Client everything is good.

Get result as array instead of Stdclass option

Hi,

Thanks for this nice little and useful class. I have just one issue.. Right now the JWT class returns StdClass object instead of a simple array.

I was wondering if we can please have the option to return the object as array as well? Maybe as an option.

It would be great because some functions like array_merge, etc don't support StdClass and make life a bit harder. All that's needed to be done is something like this:

json_decode($input, **true**) inside the jsonDecode function I guess?

Please think about it.

Thanks,
san

P.S. I know we can just typecast the object to (array) but that does not recursively work for nested arrays. The objects inside still remain of StdClass :'(

Add "sub" (subject) claim validation

As defined in the JWT Draft, Section 4.1.2 you can add a subject as a claim.

Subjects are StringOrURI, which means that it can either contain a string value or an RFC 3986 URI.

However, this PHP library does not support validating this claim yet.
Are you working on getting this in the library?

I assume it would be as simple as checking the subject of a token and compare it with an array of whitelisted subjects.

How to catch an exception?

I'm trying to use this package with Laravel, but I can't catch an exception. How to do that correctly?

public function render($request, Exception $e)
{
    if ($e instanceof DomainException) {
        return 'Caught!';
    }

    return parent::render($request, $e);
}

SignatureInvalidException but works in jwt.io

I'm using Auth0. I put the the Auth0 issued JWT token and my secret into jwt.io and it verifies sig just fine.

I do have to check the secret base64 encoded box however.

I have tried both:

$decoded = \Firebase\JWT\JWT::decode($token,$secret,['HS256']);

and

$decoded = \Firebase\JWT\JWT::decode($token,base64_decode($secret),['HS256']);

But I always get SignatureInvalidException

How do I get \Firebase\JWT\JWT::decode() to accept a base64 encoded secret key?

PHP 5.5.23, php-jwt v3.0.0

Issue while decoding JWT

I was trying to decode the generated token using decode function of https://github.com/firebase/php-jwt library.

Here is my code. I have defined private key in my configuration file using following line.
define("FIREBASE_PRIVATE_KEY","-----BEGIN PRIVATE KEY-----\nMY_VERY_VERY_LONG_KEY\n-----END PRIVATE KEY-----\n");

Here is the code to decode token.
JWT::decode($token, FIREBASE_PRIVATE_KEY, array('RS256'));

This code throws following exception.
openssl_verify(): supplied key param cannot be coerced into a public key

Can anyone suggest a solution to this?

Can put it in Controller ?

I want to build secure api application consult of http://www.toptal.com/web/cookie-free-authentication-with-json-web-tokens-an-example-in-laravel-and-angularjs

As far as work great in my routes.php, but when i move this code in my controller
if ( ! $token = JWTAuth::attempt($credentials)) {
return Response::json(false, HttpResponse::HTTP_UNAUTHORIZED);
}

it throw exception like this
Non-static method Tymon\JWTAuth\JWTAuth::attempt() should not be called statically, assuming $this from incompatible context

If you know what is happened , can you tell me what can i do ?
Should i put all the code in my routes?
thanks!

JSON_BIGINT_AS_STRING not implemented

There's an issue in some versions of PHP 5.5 where JSON_BIGINT_AS_STRING isn't implemented properly:

json_decode(): option JSON_BIGINT_AS_STRING not implemented
firebase/php-jwt/Firebase/PHP-JWT/Authentication/JWT.php(137): json_decode('{"typ":"JWT","a...', false, 512, 2)

Error on decoding jwt

Hello guys , i'm trying this library and i copy the code on the wiki but when i try to decode the jwt php report me an error.
Type: UnexpectedValueException
Message: Invalid claims encoding

i use slim php framework
you can see the error here http://piller.pillsoft.com/api/1/jwt

Add name space

When using a library such as this in a larger framework its very nice to have a properly namespaced file. Could I suggest that you namespace under your Git name:
namespace Firebase;
would be adequate and would insure that there would be no confusion between this library and anything using it that might out of necessity share its name.

Reissue JWT when expired

I'm storing jwt in a storage. of if client request with expired token which is in my storage then I want to reissue a jwt. but problem is how to get payloads from a expired jwt ?

Class ExpiredException not found

I have been trying to fix this since quite a while now. After my token expires, I get this exception:

PHP Fatal error: Class 'ExpiredException' not found in C:\wamp...\php-jwt-master\src\JWT.php on line 119.

I tried adding the use statement to explicitly use the ExpiredException class, but it still gives me this error. I am trying to redirect the user by comparing the exp claim against the current time.

No updated composer file

I've noticed that the file downloaded by composer is not the same as the last one here in the repository. The file obtained by composer (JWT.php) doesn't have "not before" ($payload->nbf) verification.

How about some documentation?

I feel this library could use some documentation, especially some mention that if the token verification fails, an exception will be thrown. Also an example of code where a try catch block is used to decode a token would help.

Thanks!

Missing/Invalid claim "kid" in auth header

Getting error "Missing claim "kid" in auth header". When I add the key ID to get rid of this error, I get "Invalid claim 'kid' in auth header." - I request you to please let me know if you know something about this. Development has stopped for 2 days because of this issue. Thanks a tonne.

// Prepare payload options
$payload = array_merge(array (
    'iss' => $service_email,
    'sub' => $service_email,
    'aud' => 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
    'iat' => $now,
    'exp' => $now + ($ttl * 60),
    'claims' => array (),
), $options);

// Prepare payload claims
$payload['uid'] = firebase_uid2fbid($uid, TRUE);
$payload['claims'] = array(
    'provider' => 'drupal',
);

// Generate token
\Firebase\JWT\JWT::$leeway = 60;
$token = \Firebase\JWT\JWT::encode($payload, $service_key, 'RS256', $service_kid);

Here, the $server_kid = config.private_key_id and $server_email = config.client_email. If this is not an issue, please tell me what is it I am doing wrong.

Cannot handle token prior to...

I'm getting errors like this sometimes:

Cannot handle token prior to 2015-06-04T06:05:30+0000

The error happens at the same time as the time above.

Why this happens and what I need to do to fix this?

Auth, login and logout

Please, add a better documentation, how to auth an user, make a login and logout with php-jwt. Cause not found nowhere in the web.

Error using RS256 - openssl_sign(): supplied key param cannot be coerced into a private key

Using HS256 works and produces the token key. but using RS256 throws the below error.
I'm using Google Cloud Compute servers if it makes any difference.

PHP Warning: openssl_sign(): supplied key param cannot be coerced into a private key in /firebase/php-jwt/src/JWT.php on line 183
PHP Fatal error: Uncaught exception 'DomainException' with message 'OpenSSL unable to sign data' in /firebase/php-jwt/src/JWT.php:185\nStack trace:\n#0 /firebase/php-jwt/src/JWT.php(154): Firebase\JWT\JWT::sign('XXX...', 'XXX...', 'RS256')\n#1 /firebase.token.php(56): Firebase\JWT\JWT::encode(Array, 'XXX...', 'RS256')\n#2 /firebase.token.php(58): create_custom_token('MYUSER', false)\n#3 {main}\n thrown in /firebase/php-jwt/src/JWT.php on line 185

Thanks !

How to catch Expired token

I got this Fatal error: Uncaught exception 'Firebase\JWT\ExpiredException' with message 'Expired token' in
I try to run try and catch, but it still come out Fatal Error.

try{
    $decoded = JWT::decode($jwt, $key, array('HS256'));
}catch(\Exception $e){
     echo 'Caught exception: ',  $e->getMessage(), "\n";
}

I am using PHP-5.4.36
How to catch this error?
Thanks!

JWT decode failed due to server time difference

I noticed there was a minor difference on the server generating the JWT and the server decoding it (on an openid connect project) and although the difference is within millisecs, very often the iat verification failed so I had to read up at the documentation and verify there is some recommendation at least for the exp and the nbf. so I've considered adding a leeway time to all time verification.

Sources:
http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef
http://openid.net/specs/openid-connect-core-1_0.html#IDToken

I've create a pull request #39 to resolve this issue a while back so I'm not sure if the workflow in this project is to see an issue first before heading for the push requests :)

[Proposal] Descriptive Exception Classes

Is it possible to have specific exceptions so they can be caught accordingly?

At the moment I am having todo the following:

    catch (UnexpectedValueException $e)
    {
        if($e->getMessage() == "Expired Token") {
           // Logic Here
        } else {
            throw $e;
        }
    }

Instead I propose the following:

Declare an exception class (i.e. Exceptions.php)

        class ExpiredTokenException extends \UnexpectedValueException {}

Handle it in the code

        if (isset($payload->exp) && time() >= $payload->exp){
            throw new ExpiredTokenException('Expired Token');
        }

Catch It

    catch (JWT\Exceptions\ExpiredTokenException $e)
    {
        // Logic Here
    }

This can be caught much easier and would have backwards compatibility with devs using UnexpectedValueException.

Cannot handle token prior to ...

I am getting this error on trying to validate a token. I explain:

1 - My AngularJS sends a http with credentials, database validates it and generates a token.
2 - AngularJS app stores the JWT token locally.
3 - On navigation the app sends the token to the server for validating expire data.
4 - Server throws this exception on trying to decode the JWT token received.
#0 C:\Server\www\routes\remember.php(17): Firebase\JWT\JWT::decode('eyJ0eXAiOiJKV1Q...', 'QWRhZ2FsIFNpc3R...', Array)
#1 [internal function]: Closure->{closure}(Object(Bullet\Request))
#2 C:\Server\www\vendor\vlucas\bulletphp\src\Bullet\App.php(311): call_user_func(Object(Closure), Object(Bullet\Request))
#3 C:\Server\www\vendor\vlucas\bulletphp\src\Bullet\App.php(195): Bullet\App->_runPath('GET', 'eyJ0eXAiOiJKV1Q...')
#4 C:\Server\www\index.php(39): Bullet\App->run(Object(Bullet\Request))
#5 {main}

composer.phar should not be in repo

Presumably composer.phar was checked in accidentally in e0a75bf? It should be removed and added to .gitignore.

I noticed because my IDE found it and started complaining about duplicate class definitions for things like Symfony\Component\Console\Input\InputOption.

Decoding with two extra digits added to the signature reports a warning

File: JWT.php

  $key = "secret";
  $payload=  ["id" => 1, "name" => "foo"];
  $jwt = JWT::encode( $payload, $key );

Encoding the payload will genrate this JWT

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwibmFtZSI6ImZvbyJ9.Q4Kee9E8o0Xfo4ADXvYA8t7dN_X_bU9K5w6tXuiSjlU

The error arise when I add two extra digits to the signature ( and only two digits )

  $fake = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwibmFtZSI6ImZvbyJ9.Q4Kee9E8o0Xfo4ADXvYA8t7dN_X_bU9K5w6tXuiSjlUxx";
  print_r( JWT::decode( $fake, $key, ['HS256'] ));

The code above will report a warning

Warning: hash_equals(): Expected known_string to be a string, boolean given in vendor/firebasephp-jwt/src/JWT.php on line 237

option JSON_BIGINT_AS_STRING not implemented

2014-06-25 06:54:49 --- EMERGENCY: ErrorException [ 2 ]: json_decode(): option JSON_BIGINT_AS_STRING not implemented ~ APPPATH/classes/JWT.php [ 137 ]

my php version is :

PHP 5.5.9-1ubuntu4.1 (cli) (built: Jun 19 2014 20:53:04)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies

so its looks like this line fails :
(version_compare(PHP_VERSION, '5.4.0', '>=') && defined('JSON_BIGINT_AS_STRING'))

Feature request - decode without verifcation

Would be nice to be able to decode the jwt without needing to verify the signature.

Eg, if you need to do additional processing when the jwt is expired.

Something like this:

public function decode($jwt, $verify = true)

Signature verification failed

Hello all, I have a problem in verifying the following signature in php-jwt, it is successfully verified using jwt.io website, the problem appears just when I try to verify it using php-jwt.
I'm not sure if I missed something, could you tell me for any solution.

eyJhbGciOiAiSFMyNTYiLCJ0eXAiOiAiSldUIn0=.eyJ0aW1lIjoxNDI4OTQyMDcxLCJzdHIiOiJrYXJ0YWwiLCJsYW5ndWFnZSI6InRyIn0=.k4ZteQMHOs+43YxakNjuDfqevgFSmgwEykrgHxO1Uic=

Is this codebase still maintained?

A few PR's building up but no commits or merges to main project for a while? Just wondering whether I stop waiting and use my own fork. Cheers, Joseph

Tag in packagist for stable version

Hi,

We are considering including your library in our application.
Could you please create a tag in packagist in order to have a stable version to include?

Thanks a lot.

JWT Token data visible when base64 decoding the token

When I encode an array using a private key using JWT::encode($array, $privatekey). I get the encrypted token.

But when I base64_decode that token, the token is totally visible.

For example, below is the token the class generated :

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VySUQiOiIyZGJhMjg1NC0wZGI0LTdhMDEtODMxNS05YWExNzA5MzQzZWUiLCJ0b2tlbl9leHBpcnkiOjE0NjU5Mzk3NzcsInNlY3JldF9pbmZvIjoibXlfc2VydmVyc19zZWNyZXRfaW5mbyJ9.36a0iYzdcgpyxAQjpqnD3kUUaoUjldDcfcjCKkCHhCk

Now, if someone just gets the token somehow, and just base64 decodes it, they can see the whole info inside the token.

Go ahead and base64 decode it and see for your self.

Please let me know if I need to know something or if Im doing something wrong with the encoding part.

Add PHP Namespaces

I read in a different issue that you did not add namespaces because you were trying to keep compatibility with PHP 5.2. Can I suggest that you break off a new version branch for newer versions of PHP?

Currently, your JWT class is colliding with another really popular package Twilio PHP.

why altering verify signature validation can be ok?

Hi
try this token

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vd3d3Lmdvb2dsZS5pdCIsImF1ZCI6Imh0dHA6Ly93d3cuZ29vZ2xlLml0IiwidXNlcm5hbWUiOiJhbmRyZWEuYmlzZWxsbyIsInJvbGVzIjpbImNhbkNyZWF0ZUNvbnRlbnQiLCJjYW5EZWxldGVDb250ZW50Il19.JQ_lBPw-YKYWeHGstnKSyOOkAwo3EJMQUTr328YW5ic

and verify with this key 9FFF4CB4B9B23C671D327AA84C2F9

here http://jwt.io/

and everything is good.

but why altering the verify signature this still correct?

for example altering the last "c" with a "d", you will obtain a corret signature. how it is possible?

thanks

OpenSSL unable to sign data while generating custom token firebase V3 with php-jwt

Warning: openssl_sign(): supplied key param cannot be coerced into a private key in /home/unitefi2/public_html/phpjwt/src/JWT.php on line 196

Fatal error: Uncaught exception 'DomainException' with message 'OpenSSL unable to sign data' in /home/unitefi2/public_html/phpjwt/src/JWT.php:198 Stack trace: #0 /home/unitefi2/public_html/phpjwt/src/JWT.php(167): Firebase\JWT\JWT::sign('eyJ0eXAiOiJKV1Q...', NULL, 'RS256') #1 /home/unitefi2/public_html/phpjwt/test/test.php(27): Firebase\JWT\JWT::encode(Array, NULL, 'RS256') #2 /home/unitefi2/public_html/phpjwt/test/test.php(38): create_custom_token('8yzfPkGWlifpe0k...') #3 {main} thrown in /home/unitefi2/public_html/phpjwt/src/JWT.php on line 198

Encode an array, get an object

I put in an associative array:

$token = array(
    "id" => $user['id'],
    "username" => $user['username'],
    "email" => $user['email'],
    "realname" => $user['realname'],
    "expires" => time() + (24 * 60 * 60)
);
$token = JWT::encode($token, token_secret);

and when I decode, I get an object:

$profile = JWT::decode($token, token_secret);
print_r($profile);

stdClass Object
(
    [id] => 1
    [username] => stephen
    [email] => [email protected]
    [realname] => stephen smith
    [expires] => 1404683315
)

Is this intentional? Right now I'm just casting it to array, but I think it would be good if it decoded to exactly what was put in?

'iat' handling doesn't conform to spec?

Hello, first of all, great library and thanks for putting it together.

My question pertains to the RFC-7519 spec for the 'iat' claim and how it is handled in this lib.

4.1.6. "iat" (Issued At) Claim

The "iat" (issued at) claim identifies the time at which the JWT was
issued. This claim can be used to determine the age of the JWT. Its
value MUST be a number containing a NumericDate value. Use of this
claim is OPTIONAL.

Since the spec says this claim is optional and doesn't specify the validity of an 'iat' claim, other than being an NumericDate value, shouldn't the library not enforce validity by default?

I see you can specify a 'leeway' time to account for clock variations and the 'iat' will be checked with this value but doesn't this break the specification? Wouldn't it be better to allow the consumer of the library to specify if the 'iat' claim should be checked outside of the NumericDate value requirement?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.