Skip to content

ynphp/php-jwt

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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 is < 7.2 or does not have libsodium installed:

composer require paragonie/sodium_compat

Example

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

$key = "example_key";
$payload = array(
    "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);

/*
 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 with RS256 (openssl)

# get the private and public key with openssl
openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout > pubkey.key

# get private and pub key with ssh-keygen
ssh-keygen -t rsa -b 2048 -C "[email protected]"
openssl rsa -in id_rsa -pubout > id_rsa_pub.key

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

$privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEArcnsWs90Uc6iU90FPombaR8SuAFNZrXuKVjVu8VyYAZgKOBt
V/bxnW/55wlfVpGX00BHCZeqtCUpjiGC1ny5DPx29UuF/Kgi9FjceF/P8dPukED6
JURclOoC/xwLPJz327NV1RJAC2j4C5OphVzBJkOfWiu/7xkQH2sF1ec7VR83/kxe
nV67iHfwsVS8gFqzxaEdiMXCABUzGn2xhReKNGJpJxTsI7KpafQsuVKAChptngKC
jr+YCKmRrjcX2bCJ6Pskai6G8JUkKJS/pAbZpIQ6uWuKVhhFxXdjSUyj0Bjsoj7g
1tQqZB2LPuzwjD39JZnRg9sPyZ32DBlX0tuYZwIDAQABAoIBAGSULWctE0vZRBc3
HjbgWwJOyn2Vu18LQcfKMwCWOCic6AAgSwgS0ijkyoPM59FpN646UCKcFV5m95Lb
kCZkTpDWeF5klCnygTBbUVWVVfrGRhZUlLEGzHIesRdF+rbcvZH4S1+iTVCNMqk4
j26wjNSBZHNCSLWvEqasQNdYGP2cvHNyzOkCbSyg9diOFIR9liQK3khpIhYpEzCH
rll/cqBfdLHFyghLwo60Q7aIFDWplADPtS0n8Py9GfgDetRT/u5KmwwSfjpRl5I2
GYZkL8WQC2yDSn0AZrCO2sfPNVvp86lbwP0p3K2z38q5s+3LxsDDulrB0TQue4Wv
0/dicukCgYEA2rWsycoO783UUE49006nfeUpczNpdGYVaPi9LfW4wRUBiQ5Bj7hZ
bPUs27iTrXEzZVxJIRyyTvP1fUfXNNgqEyGsjjJvqsx9ByeLTKemdPhVP5FHZObH
35vCO9LKzdLaIdLlgeIZG6FybZlSmOfx3jovhWGttDGTExN2+Tb+8qUCgYEAy2uF
6SeFuQMwKREXRKU3Wo5MrsJay238IsE8VxYxI2QWWPN9u2WljZ84aE2rmhlvCTZo
QlFlshIeJ/PJO7ce1n9SCJG0kl0uqfl1oZSsUtCzBU3hGpmX56ULIFums0TsILcD
t9AmUHSud4nu/VSrVp6COutL1PL3bhAUWZQ9LRsCgYBVZvG0ziDtBQut3A+KTsFa
iLyZzm6UVDRyDAcbRkNBqikyUo3JSCwrPsWoere312dBYjrwIhuCdwLaS84+RVaQ
p+qQkCNIp5b+zzM22JRIQpxPOTSOswtDRrge0h39JyOkZ4zVHeu9/VoIcAFv0cqB
g2kBBXZl0aHjpgskH5SIPQKBgQDB9MvB+8UtGzUYcwtUkJOu7G+BUh9wSHZYTRdT
kf1YWV5VghUoUUsBNgd6rFQqooWUqyPN1/63Qz8tqOz+2yO0McHuGb+qrt6Hgyv9
3NxSOlv3esJfsoN8g4mQWNMhq13Z86a/5OAjZp3TrNkLA2g7NvfFZgTwDpqNfxdo
MkgCcQKBgAL7cyflLrzqNF+JtrC30DW/z7tkBDexvPWUPs3c6F+6HVqnZCoNxdzl
qHF42i/H0VOZsyctQkZdvZEO0ciZyef6JG8+pjfg9Mzt+vIDnQhgsiuOFRSrjCWJ
ZsDzKhKRIBT5jGtDs+Wl01eMeZHNfhEdIFagr69olsm8Hs6V1P2B
-----END RSA PRIVATE KEY-----
EOD;

$publicKey = <<<EOD
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArcnsWs90Uc6iU90FPomb
aR8SuAFNZrXuKVjVu8VyYAZgKOBtV/bxnW/55wlfVpGX00BHCZeqtCUpjiGC1ny5
DPx29UuF/Kgi9FjceF/P8dPukED6JURclOoC/xwLPJz327NV1RJAC2j4C5OphVzB
JkOfWiu/7xkQH2sF1ec7VR83/kxenV67iHfwsVS8gFqzxaEdiMXCABUzGn2xhReK
NGJpJxTsI7KpafQsuVKAChptngKCjr+YCKmRrjcX2bCJ6Pskai6G8JUkKJS/pAbZ
pIQ6uWuKVhhFxXdjSUyj0Bjsoj7g1tQqZB2LPuzwjD39JZnRg9sPyZ32DBlX0tuY
ZwIDAQAB
-----END PUBLIC KEY-----
EOD;

$payload = array(
    "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 = array(
    "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 = array(
    "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";

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));

Miscellaneous

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);

Changelog

6.0.0 / 2022-01-24

  • Backwards-Compatibility Breaking Changes: See the Release Notes for more information.
  • New Key object to prevent key/algorithm type confusion (#365)
  • Add JWK support (#273)
  • Add ES256 support (#256)
  • Add ES384 support (#324)
  • Add Ed25519 support (#343)

5.0.0 / 2017-06-26

4.0.0 / 2016-07-17

  • Add support for late static binding. See #88 for details. Thanks to @chappy84!
  • Use static $timestamp instead of time() to improve unit testing. See #93 for details. Thanks to @josephmcdermott!
  • Fixes to exceptions classes. See #81 for details. Thanks to @Maks3w!
  • Fixes to PHPDoc. See #76 for details. Thanks to @akeeman!

3.0.0 / 2015-07-22

  • Minimum PHP version updated from 5.2.0 to 5.3.0.
  • Add \Firebase\JWT namespace. See #59 for details. Thanks to @Dashron!
  • Require a non-empty key to decode and verify a JWT. See #60 for details. Thanks to @sjones608!
  • Cleaner documentation blocks in the code. See #62 for details. Thanks to @johanderuijter!

2.2.0 / 2015-06-22

  • Add support for adding custom, optional JWT headers to JWT::encode(). See #53 for details. Thanks to @mcocaro!

2.1.0 / 2015-05-20

  • Add support for adding a leeway to JWT:decode() that accounts for clock skew between signing and verifying entities. Thanks to @lcabral!
  • Add support for passing an object implementing the ArrayAccess interface for $keys argument in JWT::decode(). Thanks to @aztech-dev!

2.0.0 / 2015-04-01

  • Note: It is strongly recommended that you update to > v2.0.0 to address known security vulnerabilities in prior versions when both symmetric and asymmetric keys are used together.
  • Update signature for JWT::decode(...) to require an array of supported algorithms to use when verifying token signatures.

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.

About

PEAR package for JWT

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 99.0%
  • Shell 1.0%