| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,425 @@ |
| 1 |
+ |
|
| 2 |
+[](https://packagist.org/packages/firebase/php-jwt) |
|
| 3 |
+[](https://packagist.org/packages/firebase/php-jwt) |
|
| 4 |
+[](https://packagist.org/packages/firebase/php-jwt) |
|
| 5 |
+ |
|
| 6 |
+PHP-JWT |
|
| 7 |
+======= |
|
| 8 |
+A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519). |
|
| 9 |
+ |
|
| 10 |
+Installation |
|
| 11 |
+------------ |
|
| 12 |
+ |
|
| 13 |
+Use composer to manage your dependencies and download PHP-JWT: |
|
| 14 |
+ |
|
| 15 |
+```bash |
|
| 16 |
+composer require firebase/php-jwt |
|
| 17 |
+``` |
|
| 18 |
+ |
|
| 19 |
+Optionally, install the `paragonie/sodium_compat` package from composer if your |
|
| 20 |
+php env does not have libsodium installed: |
|
| 21 |
+ |
|
| 22 |
+```bash |
|
| 23 |
+composer require paragonie/sodium_compat |
|
| 24 |
+``` |
|
| 25 |
+ |
|
| 26 |
+Example |
|
| 27 |
+------- |
|
| 28 |
+```php |
|
| 29 |
+use Firebase\JWT\JWT; |
|
| 30 |
+use Firebase\JWT\Key; |
|
| 31 |
+ |
|
| 32 |
+$key = 'example_key'; |
|
| 33 |
+$payload = [ |
|
| 34 |
+ 'iss' => 'http://example.org', |
|
| 35 |
+ 'aud' => 'http://example.com', |
|
| 36 |
+ 'iat' => 1356999524, |
|
| 37 |
+ 'nbf' => 1357000000 |
|
| 38 |
+]; |
|
| 39 |
+ |
|
| 40 |
+/** |
|
| 41 |
+ * IMPORTANT: |
|
| 42 |
+ * You must specify supported algorithms for your application. See |
|
| 43 |
+ * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 |
|
| 44 |
+ * for a list of spec-compliant algorithms. |
|
| 45 |
+ */ |
|
| 46 |
+$jwt = JWT::encode($payload, $key, 'HS256'); |
|
| 47 |
+$decoded = JWT::decode($jwt, new Key($key, 'HS256')); |
|
| 48 |
+print_r($decoded); |
|
| 49 |
+ |
|
| 50 |
+// Pass a stdClass in as the third parameter to get the decoded header values |
|
| 51 |
+$headers = new stdClass(); |
|
| 52 |
+$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers); |
|
| 53 |
+print_r($headers); |
|
| 54 |
+ |
|
| 55 |
+/* |
|
| 56 |
+ NOTE: This will now be an object instead of an associative array. To get |
|
| 57 |
+ an associative array, you will need to cast it as such: |
|
| 58 |
+*/ |
|
| 59 |
+ |
|
| 60 |
+$decoded_array = (array) $decoded; |
|
| 61 |
+ |
|
| 62 |
+/** |
|
| 63 |
+ * You can add a leeway to account for when there is a clock skew times between |
|
| 64 |
+ * the signing and verifying servers. It is recommended that this leeway should |
|
| 65 |
+ * not be bigger than a few minutes. |
|
| 66 |
+ * |
|
| 67 |
+ * Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef |
|
| 68 |
+ */ |
|
| 69 |
+JWT::$leeway = 60; // $leeway in seconds |
|
| 70 |
+$decoded = JWT::decode($jwt, new Key($key, 'HS256')); |
|
| 71 |
+``` |
|
| 72 |
+Example encode/decode headers |
|
| 73 |
+------- |
|
| 74 |
+Decoding the JWT headers without verifying the JWT first is NOT recommended, and is not supported by |
|
| 75 |
+this library. This is because without verifying the JWT, the header values could have been tampered with. |
|
| 76 |
+Any value pulled from an unverified header should be treated as if it could be any string sent in from an |
|
| 77 |
+attacker. If this is something you still want to do in your application for whatever reason, it's possible to |
|
| 78 |
+decode the header values manually simply by calling `json_decode` and `base64_decode` on the JWT |
|
| 79 |
+header part: |
|
| 80 |
+```php |
|
| 81 |
+use Firebase\JWT\JWT; |
|
| 82 |
+ |
|
| 83 |
+$key = 'example_key'; |
|
| 84 |
+$payload = [ |
|
| 85 |
+ 'iss' => 'http://example.org', |
|
| 86 |
+ 'aud' => 'http://example.com', |
|
| 87 |
+ 'iat' => 1356999524, |
|
| 88 |
+ 'nbf' => 1357000000 |
|
| 89 |
+]; |
|
| 90 |
+ |
|
| 91 |
+$headers = [ |
|
| 92 |
+ 'x-forwarded-for' => 'www.google.com' |
|
| 93 |
+]; |
|
| 94 |
+ |
|
| 95 |
+// Encode headers in the JWT string |
|
| 96 |
+$jwt = JWT::encode($payload, $key, 'HS256', null, $headers); |
|
| 97 |
+ |
|
| 98 |
+// Decode headers from the JWT string WITHOUT validation |
|
| 99 |
+// **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified. |
|
| 100 |
+// These headers could be any value sent by an attacker. |
|
| 101 |
+list($headersB64, $payloadB64, $sig) = explode('.', $jwt);
|
|
| 102 |
+$decoded = json_decode(base64_decode($headersB64), true); |
|
| 103 |
+ |
|
| 104 |
+print_r($decoded); |
|
| 105 |
+``` |
|
| 106 |
+Example with RS256 (openssl) |
|
| 107 |
+---------------------------- |
|
| 108 |
+```php |
|
| 109 |
+use Firebase\JWT\JWT; |
|
| 110 |
+use Firebase\JWT\Key; |
|
| 111 |
+ |
|
| 112 |
+$privateKey = <<<EOD |
|
| 113 |
+-----BEGIN RSA PRIVATE KEY----- |
|
| 114 |
+MIIEowIBAAKCAQEAuzWHNM5f+amCjQztc5QTfJfzCC5J4nuW+L/aOxZ4f8J3Frew |
|
| 115 |
+M2c/dufrnmedsApb0By7WhaHlcqCh/ScAPyJhzkPYLae7bTVro3hok0zDITR8F6S |
|
| 116 |
+JGL42JAEUk+ILkPI+DONM0+3vzk6Kvfe548tu4czCuqU8BGVOlnp6IqBHhAswNMM |
|
| 117 |
+78pos/2z0CjPM4tbeXqSTTbNkXRboxjU29vSopcT51koWOgiTf3C7nJUoMWZHZI5 |
|
| 118 |
+HqnIhPAG9yv8HAgNk6CMk2CadVHDo4IxjxTzTTqo1SCSH2pooJl9O8at6kkRYsrZ |
|
| 119 |
+WwsKlOFE2LUce7ObnXsYihStBUDoeBQlGG/BwQIDAQABAoIBAFtGaOqNKGwggn9k |
|
| 120 |
+6yzr6GhZ6Wt2rh1Xpq8XUz514UBhPxD7dFRLpbzCrLVpzY80LbmVGJ9+1pJozyWc |
|
| 121 |
+VKeCeUdNwbqkr240Oe7GTFmGjDoxU+5/HX/SJYPpC8JZ9oqgEA87iz+WQX9hVoP2 |
|
| 122 |
+oF6EB4ckDvXmk8FMwVZW2l2/kd5mrEVbDaXKxhvUDf52iVD+sGIlTif7mBgR99/b |
|
| 123 |
+c3qiCnxCMmfYUnT2eh7Vv2LhCR/G9S6C3R4lA71rEyiU3KgsGfg0d82/XWXbegJW |
|
| 124 |
+h3QbWNtQLxTuIvLq5aAryV3PfaHlPgdgK0ft6ocU2de2FagFka3nfVEyC7IUsNTK |
|
| 125 |
+bq6nhAECgYEA7d/0DPOIaItl/8BWKyCuAHMss47j0wlGbBSHdJIiS55akMvnAG0M |
|
| 126 |
+39y22Qqfzh1at9kBFeYeFIIU82ZLF3xOcE3z6pJZ4Dyvx4BYdXH77odo9uVK9s1l |
|
| 127 |
+3T3BlMcqd1hvZLMS7dviyH79jZo4CXSHiKzc7pQ2YfK5eKxKqONeXuECgYEAyXlG |
|
| 128 |
+vonaus/YTb1IBei9HwaccnQ/1HRn6MvfDjb7JJDIBhNClGPt6xRlzBbSZ73c2QEC |
|
| 129 |
+6Fu9h36K/HZ2qcLd2bXiNyhIV7b6tVKk+0Psoj0dL9EbhsD1OsmE1nTPyAc9XZbb |
|
| 130 |
+OPYxy+dpBCUA8/1U9+uiFoCa7mIbWcSQ+39gHuECgYAz82pQfct30aH4JiBrkNqP |
|
| 131 |
+nJfRq05UY70uk5k1u0ikLTRoVS/hJu/d4E1Kv4hBMqYCavFSwAwnvHUo51lVCr/y |
|
| 132 |
+xQOVYlsgnwBg2MX4+GjmIkqpSVCC8D7j/73MaWb746OIYZervQ8dbKahi2HbpsiG |
|
| 133 |
+8AHcVSA/agxZr38qvWV54QKBgCD5TlDE8x18AuTGQ9FjxAAd7uD0kbXNz2vUYg9L |
|
| 134 |
+hFL5tyL3aAAtUrUUw4xhd9IuysRhW/53dU+FsG2dXdJu6CxHjlyEpUJl2iZu/j15 |
|
| 135 |
+YnMzGWHIEX8+eWRDsw/+Ujtko/B7TinGcWPz3cYl4EAOiCeDUyXnqnO1btCEUU44 |
|
| 136 |
+DJ1BAoGBAJuPD27ErTSVtId90+M4zFPNibFP50KprVdc8CR37BE7r8vuGgNYXmnI |
|
| 137 |
+RLnGP9p3pVgFCktORuYS2J/6t84I3+A17nEoB4xvhTLeAinAW/uTQOUmNicOP4Ek |
|
| 138 |
+2MsLL2kHgL8bLTmvXV4FX+PXphrDKg1XxzOYn0otuoqdAQrkK4og |
|
| 139 |
+-----END RSA PRIVATE KEY----- |
|
| 140 |
+EOD; |
|
| 141 |
+ |
|
| 142 |
+$publicKey = <<<EOD |
|
| 143 |
+-----BEGIN PUBLIC KEY----- |
|
| 144 |
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzWHNM5f+amCjQztc5QT |
|
| 145 |
+fJfzCC5J4nuW+L/aOxZ4f8J3FrewM2c/dufrnmedsApb0By7WhaHlcqCh/ScAPyJ |
|
| 146 |
+hzkPYLae7bTVro3hok0zDITR8F6SJGL42JAEUk+ILkPI+DONM0+3vzk6Kvfe548t |
|
| 147 |
+u4czCuqU8BGVOlnp6IqBHhAswNMM78pos/2z0CjPM4tbeXqSTTbNkXRboxjU29vS |
|
| 148 |
+opcT51koWOgiTf3C7nJUoMWZHZI5HqnIhPAG9yv8HAgNk6CMk2CadVHDo4IxjxTz |
|
| 149 |
+TTqo1SCSH2pooJl9O8at6kkRYsrZWwsKlOFE2LUce7ObnXsYihStBUDoeBQlGG/B |
|
| 150 |
+wQIDAQAB |
|
| 151 |
+-----END PUBLIC KEY----- |
|
| 152 |
+EOD; |
|
| 153 |
+ |
|
| 154 |
+$payload = [ |
|
| 155 |
+ 'iss' => 'example.org', |
|
| 156 |
+ 'aud' => 'example.com', |
|
| 157 |
+ 'iat' => 1356999524, |
|
| 158 |
+ 'nbf' => 1357000000 |
|
| 159 |
+]; |
|
| 160 |
+ |
|
| 161 |
+$jwt = JWT::encode($payload, $privateKey, 'RS256'); |
|
| 162 |
+echo "Encode:\n" . print_r($jwt, true) . "\n"; |
|
| 163 |
+ |
|
| 164 |
+$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256')); |
|
| 165 |
+ |
|
| 166 |
+/* |
|
| 167 |
+ NOTE: This will now be an object instead of an associative array. To get |
|
| 168 |
+ an associative array, you will need to cast it as such: |
|
| 169 |
+*/ |
|
| 170 |
+ |
|
| 171 |
+$decoded_array = (array) $decoded; |
|
| 172 |
+echo "Decode:\n" . print_r($decoded_array, true) . "\n"; |
|
| 173 |
+``` |
|
| 174 |
+ |
|
| 175 |
+Example with a passphrase |
|
| 176 |
+------------------------- |
|
| 177 |
+ |
|
| 178 |
+```php |
|
| 179 |
+use Firebase\JWT\JWT; |
|
| 180 |
+use Firebase\JWT\Key; |
|
| 181 |
+ |
|
| 182 |
+// Your passphrase |
|
| 183 |
+$passphrase = '[YOUR_PASSPHRASE]'; |
|
| 184 |
+ |
|
| 185 |
+// Your private key file with passphrase |
|
| 186 |
+// Can be generated with "ssh-keygen -t rsa -m pem" |
|
| 187 |
+$privateKeyFile = '/path/to/key-with-passphrase.pem'; |
|
| 188 |
+ |
|
| 189 |
+// Create a private key of type "resource" |
|
| 190 |
+$privateKey = openssl_pkey_get_private( |
|
| 191 |
+ file_get_contents($privateKeyFile), |
|
| 192 |
+ $passphrase |
|
| 193 |
+); |
|
| 194 |
+ |
|
| 195 |
+$payload = [ |
|
| 196 |
+ 'iss' => 'example.org', |
|
| 197 |
+ 'aud' => 'example.com', |
|
| 198 |
+ 'iat' => 1356999524, |
|
| 199 |
+ 'nbf' => 1357000000 |
|
| 200 |
+]; |
|
| 201 |
+ |
|
| 202 |
+$jwt = JWT::encode($payload, $privateKey, 'RS256'); |
|
| 203 |
+echo "Encode:\n" . print_r($jwt, true) . "\n"; |
|
| 204 |
+ |
|
| 205 |
+// Get public key from the private key, or pull from from a file. |
|
| 206 |
+$publicKey = openssl_pkey_get_details($privateKey)['key']; |
|
| 207 |
+ |
|
| 208 |
+$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256')); |
|
| 209 |
+echo "Decode:\n" . print_r((array) $decoded, true) . "\n"; |
|
| 210 |
+``` |
|
| 211 |
+ |
|
| 212 |
+Example with EdDSA (libsodium and Ed25519 signature) |
|
| 213 |
+---------------------------- |
|
| 214 |
+```php |
|
| 215 |
+use Firebase\JWT\JWT; |
|
| 216 |
+use Firebase\JWT\Key; |
|
| 217 |
+ |
|
| 218 |
+// Public and private keys are expected to be Base64 encoded. The last |
|
| 219 |
+// non-empty line is used so that keys can be generated with |
|
| 220 |
+// sodium_crypto_sign_keypair(). The secret keys generated by other tools may |
|
| 221 |
+// need to be adjusted to match the input expected by libsodium. |
|
| 222 |
+ |
|
| 223 |
+$keyPair = sodium_crypto_sign_keypair(); |
|
| 224 |
+ |
|
| 225 |
+$privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair)); |
|
| 226 |
+ |
|
| 227 |
+$publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair)); |
|
| 228 |
+ |
|
| 229 |
+$payload = [ |
|
| 230 |
+ 'iss' => 'example.org', |
|
| 231 |
+ 'aud' => 'example.com', |
|
| 232 |
+ 'iat' => 1356999524, |
|
| 233 |
+ 'nbf' => 1357000000 |
|
| 234 |
+]; |
|
| 235 |
+ |
|
| 236 |
+$jwt = JWT::encode($payload, $privateKey, 'EdDSA'); |
|
| 237 |
+echo "Encode:\n" . print_r($jwt, true) . "\n"; |
|
| 238 |
+ |
|
| 239 |
+$decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA')); |
|
| 240 |
+echo "Decode:\n" . print_r((array) $decoded, true) . "\n"; |
|
| 241 |
+```` |
|
| 242 |
+ |
|
| 243 |
+Example with multiple keys |
|
| 244 |
+-------------------------- |
|
| 245 |
+```php |
|
| 246 |
+use Firebase\JWT\JWT; |
|
| 247 |
+use Firebase\JWT\Key; |
|
| 248 |
+ |
|
| 249 |
+// Example RSA keys from previous example |
|
| 250 |
+// $privateKey1 = '...'; |
|
| 251 |
+// $publicKey1 = '...'; |
|
| 252 |
+ |
|
| 253 |
+// Example EdDSA keys from previous example |
|
| 254 |
+// $privateKey2 = '...'; |
|
| 255 |
+// $publicKey2 = '...'; |
|
| 256 |
+ |
|
| 257 |
+$payload = [ |
|
| 258 |
+ 'iss' => 'example.org', |
|
| 259 |
+ 'aud' => 'example.com', |
|
| 260 |
+ 'iat' => 1356999524, |
|
| 261 |
+ 'nbf' => 1357000000 |
|
| 262 |
+]; |
|
| 263 |
+ |
|
| 264 |
+$jwt1 = JWT::encode($payload, $privateKey1, 'RS256', 'kid1'); |
|
| 265 |
+$jwt2 = JWT::encode($payload, $privateKey2, 'EdDSA', 'kid2'); |
|
| 266 |
+echo "Encode 1:\n" . print_r($jwt1, true) . "\n"; |
|
| 267 |
+echo "Encode 2:\n" . print_r($jwt2, true) . "\n"; |
|
| 268 |
+ |
|
| 269 |
+$keys = [ |
|
| 270 |
+ 'kid1' => new Key($publicKey1, 'RS256'), |
|
| 271 |
+ 'kid2' => new Key($publicKey2, 'EdDSA'), |
|
| 272 |
+]; |
|
| 273 |
+ |
|
| 274 |
+$decoded1 = JWT::decode($jwt1, $keys); |
|
| 275 |
+$decoded2 = JWT::decode($jwt2, $keys); |
|
| 276 |
+ |
|
| 277 |
+echo "Decode 1:\n" . print_r((array) $decoded1, true) . "\n"; |
|
| 278 |
+echo "Decode 2:\n" . print_r((array) $decoded2, true) . "\n"; |
|
| 279 |
+``` |
|
| 280 |
+ |
|
| 281 |
+Using JWKs |
|
| 282 |
+---------- |
|
| 283 |
+ |
|
| 284 |
+```php |
|
| 285 |
+use Firebase\JWT\JWK; |
|
| 286 |
+use Firebase\JWT\JWT; |
|
| 287 |
+ |
|
| 288 |
+// Set of keys. The "keys" key is required. For example, the JSON response to |
|
| 289 |
+// this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk |
|
| 290 |
+$jwks = ['keys' => []]; |
|
| 291 |
+ |
|
| 292 |
+// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key |
|
| 293 |
+// objects. Pass this as the second parameter to JWT::decode. |
|
| 294 |
+JWT::decode($jwt, JWK::parseKeySet($jwks)); |
|
| 295 |
+``` |
|
| 296 |
+ |
|
| 297 |
+Using Cached Key Sets |
|
| 298 |
+--------------------- |
|
| 299 |
+ |
|
| 300 |
+The `CachedKeySet` class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI. |
|
| 301 |
+This has the following advantages: |
|
| 302 |
+ |
|
| 303 |
+1. The results are cached for performance. |
|
| 304 |
+2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation. |
|
| 305 |
+3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second. |
|
| 306 |
+ |
|
| 307 |
+```php |
|
| 308 |
+use Firebase\JWT\CachedKeySet; |
|
| 309 |
+use Firebase\JWT\JWT; |
|
| 310 |
+ |
|
| 311 |
+// The URI for the JWKS you wish to cache the results from |
|
| 312 |
+$jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk'; |
|
| 313 |
+ |
|
| 314 |
+// Create an HTTP client (can be any PSR-7 compatible HTTP client) |
|
| 315 |
+$httpClient = new GuzzleHttp\Client(); |
|
| 316 |
+ |
|
| 317 |
+// Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory) |
|
| 318 |
+$httpFactory = new GuzzleHttp\Psr\HttpFactory(); |
|
| 319 |
+ |
|
| 320 |
+// Create a cache item pool (can be any PSR-6 compatible cache item pool) |
|
| 321 |
+$cacheItemPool = Phpfastcache\CacheManager::getInstance('files');
|
|
| 322 |
+ |
|
| 323 |
+$keySet = new CachedKeySet( |
|
| 324 |
+ $jwksUri, |
|
| 325 |
+ $httpClient, |
|
| 326 |
+ $httpFactory, |
|
| 327 |
+ $cacheItemPool, |
|
| 328 |
+ null, // $expiresAfter int seconds to set the JWKS to expire |
|
| 329 |
+ true // $rateLimit true to enable rate limit of 10 RPS on lookup of invalid keys |
|
| 330 |
+); |
|
| 331 |
+ |
|
| 332 |
+$jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above |
|
| 333 |
+$decoded = JWT::decode($jwt, $keySet); |
|
| 334 |
+``` |
|
| 335 |
+ |
|
| 336 |
+Miscellaneous |
|
| 337 |
+------------- |
|
| 338 |
+ |
|
| 339 |
+#### Exception Handling |
|
| 340 |
+ |
|
| 341 |
+When a call to `JWT::decode` is invalid, it will throw one of the following exceptions: |
|
| 342 |
+ |
|
| 343 |
+```php |
|
| 344 |
+use Firebase\JWT\JWT; |
|
| 345 |
+use Firebase\JWT\SignatureInvalidException; |
|
| 346 |
+use Firebase\JWT\BeforeValidException; |
|
| 347 |
+use Firebase\JWT\ExpiredException; |
|
| 348 |
+use DomainException; |
|
| 349 |
+use InvalidArgumentException; |
|
| 350 |
+use UnexpectedValueException; |
|
| 351 |
+ |
|
| 352 |
+try {
|
|
| 353 |
+ $decoded = JWT::decode($jwt, $keys); |
|
| 354 |
+} catch (InvalidArgumentException $e) {
|
|
| 355 |
+ // provided key/key-array is empty or malformed. |
|
| 356 |
+} catch (DomainException $e) {
|
|
| 357 |
+ // provided algorithm is unsupported OR |
|
| 358 |
+ // provided key is invalid OR |
|
| 359 |
+ // unknown error thrown in openSSL or libsodium OR |
|
| 360 |
+ // libsodium is required but not available. |
|
| 361 |
+} catch (SignatureInvalidException $e) {
|
|
| 362 |
+ // provided JWT signature verification failed. |
|
| 363 |
+} catch (BeforeValidException $e) {
|
|
| 364 |
+ // provided JWT is trying to be used before "nbf" claim OR |
|
| 365 |
+ // provided JWT is trying to be used before "iat" claim. |
|
| 366 |
+} catch (ExpiredException $e) {
|
|
| 367 |
+ // provided JWT is trying to be used after "exp" claim. |
|
| 368 |
+} catch (UnexpectedValueException $e) {
|
|
| 369 |
+ // provided JWT is malformed OR |
|
| 370 |
+ // provided JWT is missing an algorithm / using an unsupported algorithm OR |
|
| 371 |
+ // provided JWT algorithm does not match provided key OR |
|
| 372 |
+ // provided key ID in key/key-array is empty or invalid. |
|
| 373 |
+} |
|
| 374 |
+``` |
|
| 375 |
+ |
|
| 376 |
+All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`, and can be simplified |
|
| 377 |
+like this: |
|
| 378 |
+ |
|
| 379 |
+```php |
|
| 380 |
+use Firebase\JWT\JWT; |
|
| 381 |
+use UnexpectedValueException; |
|
| 382 |
+try {
|
|
| 383 |
+ $decoded = JWT::decode($jwt, $keys); |
|
| 384 |
+} catch (LogicException $e) {
|
|
| 385 |
+ // errors having to do with environmental setup or malformed JWT Keys |
|
| 386 |
+} catch (UnexpectedValueException $e) {
|
|
| 387 |
+ // errors having to do with JWT signature and claims |
|
| 388 |
+} |
|
| 389 |
+``` |
|
| 390 |
+ |
|
| 391 |
+#### Casting to array |
|
| 392 |
+ |
|
| 393 |
+The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays |
|
| 394 |
+instead, you can do the following: |
|
| 395 |
+ |
|
| 396 |
+```php |
|
| 397 |
+// return type is stdClass |
|
| 398 |
+$decoded = JWT::decode($jwt, $keys); |
|
| 399 |
+ |
|
| 400 |
+// cast to array |
|
| 401 |
+$decoded = json_decode(json_encode($decoded), true); |
|
| 402 |
+``` |
|
| 403 |
+ |
|
| 404 |
+Tests |
|
| 405 |
+----- |
|
| 406 |
+Run the tests using phpunit: |
|
| 407 |
+ |
|
| 408 |
+```bash |
|
| 409 |
+$ pear install PHPUnit |
|
| 410 |
+$ phpunit --configuration phpunit.xml.dist |
|
| 411 |
+PHPUnit 3.7.10 by Sebastian Bergmann. |
|
| 412 |
+..... |
|
| 413 |
+Time: 0 seconds, Memory: 2.50Mb |
|
| 414 |
+OK (5 tests, 5 assertions) |
|
| 415 |
+``` |
|
| 416 |
+ |
|
| 417 |
+New Lines in private keys |
|
| 418 |
+----- |
|
| 419 |
+ |
|
| 420 |
+If your private key contains `\n` characters, be sure to wrap it in double quotes `""` |
|
| 421 |
+and not single quotes `''` in order to properly interpret the escaped characters. |
|
| 422 |
+ |
|
| 423 |
+License |
|
| 424 |
+------- |
|
| 425 |
+[3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause). |
| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,200 +0,0 @@ |
| 1 |
-[](https://travis-ci.org/firebase/php-jwt) |
|
| 2 |
-[](https://packagist.org/packages/firebase/php-jwt) |
|
| 3 |
-[](https://packagist.org/packages/firebase/php-jwt) |
|
| 4 |
-[](https://packagist.org/packages/firebase/php-jwt) |
|
| 5 |
- |
|
| 6 |
-PHP-JWT |
|
| 7 |
-======= |
|
| 8 |
-A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519). |
|
| 9 |
- |
|
| 10 |
-Installation |
|
| 11 |
- |
|
| 12 |
-Use composer to manage your dependencies and download PHP-JWT: |
|
| 13 |
- |
|
| 14 |
-```bash |
|
| 15 |
-composer require firebase/php-jwt |
|
| 16 |
-``` |
|
| 17 |
- |
|
| 18 |
-Example |
|
| 19 |
-```php |
|
| 20 |
-<?php |
|
| 21 |
-use \Firebase\JWT\JWT; |
|
| 22 |
- |
|
| 23 |
-$key = "example_key"; |
|
| 24 |
-$payload = array( |
|
| 25 |
- "iss" => "http://example.org", |
|
| 26 |
- "aud" => "http://example.com", |
|
| 27 |
- "iat" => 1356999524, |
|
| 28 |
- "nbf" => 1357000000 |
|
| 29 |
-); |
|
| 30 |
- |
|
| 31 |
-/** |
|
| 32 |
- * IMPORTANT: |
|
| 33 |
- * You must specify supported algorithms for your application. See |
|
| 34 |
- * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 |
|
| 35 |
- * for a list of spec-compliant algorithms. |
|
| 36 |
- */ |
|
| 37 |
-$jwt = JWT::encode($payload, $key); |
|
| 38 |
-$decoded = JWT::decode($jwt, $key, array('HS256'));
|
|
| 39 |
- |
|
| 40 |
-print_r($decoded); |
|
| 41 |
- |
|
| 42 |
-/* |
|
| 43 |
- NOTE: This will now be an object instead of an associative array. To get |
|
| 44 |
- an associative array, you will need to cast it as such: |
|
| 45 |
-*/ |
|
| 46 |
- |
|
| 47 |
-$decoded_array = (array) $decoded; |
|
| 48 |
- |
|
| 49 |
-/** |
|
| 50 |
- * You can add a leeway to account for when there is a clock skew times between |
|
| 51 |
- * the signing and verifying servers. It is recommended that this leeway should |
|
| 52 |
- * not be bigger than a few minutes. |
|
| 53 |
- * |
|
| 54 |
- * Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef |
|
| 55 |
- */ |
|
| 56 |
-JWT::$leeway = 60; // $leeway in seconds |
|
| 57 |
-$decoded = JWT::decode($jwt, $key, array('HS256'));
|
|
| 58 |
- |
|
| 59 |
-?> |
|
| 60 |
-``` |
|
| 61 |
-Example with RS256 (openssl) |
|
| 62 |
-```php |
|
| 63 |
-<?php |
|
| 64 |
-use \Firebase\JWT\JWT; |
|
| 65 |
- |
|
| 66 |
-$privateKey = <<<EOD |
|
| 67 |
-MIICXAIBAAKBgQC8kGa1pSjbSYZVebtTRBLxBz5H4i2p/llLCrEeQhta5kaQu/Rn |
|
| 68 |
-vuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t0tyazyZ8JXw+KgXTxldMPEL9 |
|
| 69 |
-5+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4ehde/zUxo6UvS7UrBQIDAQAB |
|
| 70 |
-AoGAb/MXV46XxCFRxNuB8LyAtmLDgi/xRnTAlMHjSACddwkyKem8//8eZtw9fzxz |
|
| 71 |
-bWZ/1/doQOuHBGYZU8aDzzj59FZ78dyzNFoF91hbvZKkg+6wGyd/LrGVEB+Xre0J |
|
| 72 |
-Nil0GReM2AHDNZUYRv+HYJPIOrB0CRczLQsgFJ8K6aAD6F0CQQDzbpjYdx10qgK1 |
|
| 73 |
-cP59UHiHjPZYC0loEsk7s+hUmT3QHerAQJMZWC11Qrn2N+ybwwNblDKv+s5qgMQ5 |
|
| 74 |
-5tNoQ9IfAkEAxkyffU6ythpg/H0Ixe1I2rd0GbF05biIzO/i77Det3n4YsJVlDck |
|
| 75 |
-ZkcvY3SK2iRIL4c9yY6hlIhs+K9wXTtGWwJBAO9Dskl48mO7woPR9uD22jDpNSwe |
|
| 76 |
-k90OMepTjzSvlhjbfuPN1IdhqvSJTDychRwn1kIJ7LQZgQ8fVz9OCFZ/6qMCQGOb |
|
| 77 |
-qaGwHmUK6xzpUbbacnYrIM6nLSkXgOAwv7XXCojvY614ILTK3iXiLBOxPu5Eu13k |
|
| 78 |
-eUz9sHyD6vkgZzjtxXECQAkp4Xerf5TGfQXGXhxIX52yH+N2LtujCdkQZjXAsGdm |
|
| 79 |
-B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM= |
|
| 80 |
-EOD; |
|
| 81 |
- |
|
| 82 |
-$publicKey = <<<EOD |
|
| 83 |
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H |
|
| 84 |
-4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t |
|
| 85 |
-0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4 |
|
| 86 |
-ehde/zUxo6UvS7UrBQIDAQAB |
|
| 87 |
-EOD; |
|
| 88 |
- |
|
| 89 |
-$payload = array( |
|
| 90 |
- "iss" => "example.org", |
|
| 91 |
- "aud" => "example.com", |
|
| 92 |
- "iat" => 1356999524, |
|
| 93 |
- "nbf" => 1357000000 |
|
| 94 |
-); |
|
| 95 |
- |
|
| 96 |
-$jwt = JWT::encode($payload, $privateKey, 'RS256'); |
|
| 97 |
-echo "Encode:\n" . print_r($jwt, true) . "\n"; |
|
| 98 |
- |
|
| 99 |
-$decoded = JWT::decode($jwt, $publicKey, array('RS256'));
|
|
| 100 |
- |
|
| 101 |
-/* |
|
| 102 |
- NOTE: This will now be an object instead of an associative array. To get |
|
| 103 |
- an associative array, you will need to cast it as such: |
|
| 104 |
-*/ |
|
| 105 |
- |
|
| 106 |
-$decoded_array = (array) $decoded; |
|
| 107 |
-echo "Decode:\n" . print_r($decoded_array, true) . "\n"; |
|
| 108 |
-?> |
|
| 109 |
-``` |
|
| 110 |
- |
|
| 111 |
-Changelog |
|
| 112 |
- |
|
| 113 |
-#### 5.0.0 / 2017-06-26 |
|
| 114 |
-- Support RS384 and RS512. |
|
| 115 |
- See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)! |
|
| 116 |
-- Add an example for RS256 openssl. |
|
| 117 |
- See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)! |
|
| 118 |
-- Detect invalid Base64 encoding in signature. |
|
| 119 |
- See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)! |
|
| 120 |
-- Update `JWT::verify` to handle OpenSSL errors. |
|
| 121 |
- See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)! |
|
| 122 |
-- Add `array` type hinting to `decode` method |
|
| 123 |
- See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)! |
|
| 124 |
-- Add all JSON error types. |
|
| 125 |
- See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)! |
|
| 126 |
-- Bugfix 'kid' not in given key list. |
|
| 127 |
- See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)! |
|
| 128 |
-- Miscellaneous cleanup, documentation and test fixes. |
|
| 129 |
- See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115), |
|
| 130 |
- [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and |
|
| 131 |
- [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman), |
|
| 132 |
- [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)! |
|
| 133 |
- |
|
| 134 |
-#### 4.0.0 / 2016-07-17 |
|
| 135 |
-- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! |
|
| 136 |
-- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! |
|
| 137 |
-- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! |
|
| 138 |
-- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! |
|
| 139 |
- |
|
| 140 |
-#### 3.0.0 / 2015-07-22 |
|
| 141 |
-- Minimum PHP version updated from `5.2.0` to `5.3.0`. |
|
| 142 |
-- Add `\Firebase\JWT` namespace. See |
|
| 143 |
-[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to |
|
| 144 |
-[@Dashron](https://github.com/Dashron)! |
|
| 145 |
-- Require a non-empty key to decode and verify a JWT. See |
|
| 146 |
-[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to |
|
| 147 |
-[@sjones608](https://github.com/sjones608)! |
|
| 148 |
-- Cleaner documentation blocks in the code. See |
|
| 149 |
-[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to |
|
| 150 |
-[@johanderuijter](https://github.com/johanderuijter)! |
|
| 151 |
- |
|
| 152 |
-#### 2.2.0 / 2015-06-22 |
|
| 153 |
-- Add support for adding custom, optional JWT headers to `JWT::encode()`. See |
|
| 154 |
-[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to |
|
| 155 |
-[@mcocaro](https://github.com/mcocaro)! |
|
| 156 |
- |
|
| 157 |
-#### 2.1.0 / 2015-05-20 |
|
| 158 |
-- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew |
|
| 159 |
-between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)! |
|
| 160 |
-- Add support for passing an object implementing the `ArrayAccess` interface for |
|
| 161 |
-`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)! |
|
| 162 |
- |
|
| 163 |
-#### 2.0.0 / 2015-04-01 |
|
| 164 |
-- **Note**: It is strongly recommended that you update to > v2.0.0 to address |
|
| 165 |
- known security vulnerabilities in prior versions when both symmetric and |
|
| 166 |
- asymmetric keys are used together. |
|
| 167 |
-- Update signature for `JWT::decode(...)` to require an array of supported |
|
| 168 |
- algorithms to use when verifying token signatures. |
|
| 169 |
- |
|
| 170 |
- |
|
| 171 |
-Tests |
|
| 172 |
-Run the tests using phpunit: |
|
| 173 |
- |
|
| 174 |
-```bash |
|
| 175 |
-$ pear install PHPUnit |
|
| 176 |
-$ phpunit --configuration phpunit.xml.dist |
|
| 177 |
-PHPUnit 3.7.10 by Sebastian Bergmann. |
|
| 178 |
-..... |
|
| 179 |
-Time: 0 seconds, Memory: 2.50Mb |
|
| 180 |
-OK (5 tests, 5 assertions) |
|
| 181 |
-``` |
|
| 182 |
- |
|
| 183 |
-New Lines in private keys |
|
| 184 |
- |
|
| 185 |
-If your private key contains `\n` characters, be sure to wrap it in double quotes `""` |
|
| 186 |
-and not single quotes `''` in order to properly interpret the escaped characters. |
|
| 187 |
- |
|
| 188 |
-License |
|
| 189 |
-[3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause). |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,200 @@ |
| 1 |
+[](https://travis-ci.org/firebase/php-jwt) |
|
| 2 |
+[](https://packagist.org/packages/firebase/php-jwt) |
|
| 3 |
+[](https://packagist.org/packages/firebase/php-jwt) |
|
| 4 |
+[](https://packagist.org/packages/firebase/php-jwt) |
|
| 5 |
+ |
|
| 6 |
+PHP-JWT |
|
| 7 |
+======= |
|
| 8 |
+A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519). |
|
| 9 |
+ |
|
| 10 |
+Installation |
|
| 11 |
+------------ |
|
| 12 |
+ |
|
| 13 |
+Use composer to manage your dependencies and download PHP-JWT: |
|
| 14 |
+ |
|
| 15 |
+```bash |
|
| 16 |
+composer require firebase/php-jwt |
|
| 17 |
+``` |
|
| 18 |
+ |
|
| 19 |
+Example |
|
| 20 |
+------- |
|
| 21 |
+```php |
|
| 22 |
+<?php |
|
| 23 |
+use \Firebase\JWT\JWT; |
|
| 24 |
+ |
|
| 25 |
+$key = "example_key"; |
|
| 26 |
+$payload = array( |
|
| 27 |
+ "iss" => "http://example.org", |
|
| 28 |
+ "aud" => "http://example.com", |
|
| 29 |
+ "iat" => 1356999524, |
|
| 30 |
+ "nbf" => 1357000000 |
|
| 31 |
+); |
|
| 32 |
+ |
|
| 33 |
+/** |
|
| 34 |
+ * IMPORTANT: |
|
| 35 |
+ * You must specify supported algorithms for your application. See |
|
| 36 |
+ * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 |
|
| 37 |
+ * for a list of spec-compliant algorithms. |
|
| 38 |
+ */ |
|
| 39 |
+$jwt = JWT::encode($payload, $key); |
|
| 40 |
+$decoded = JWT::decode($jwt, $key, array('HS256'));
|
|
| 41 |
+ |
|
| 42 |
+print_r($decoded); |
|
| 43 |
+ |
|
| 44 |
+/* |
|
| 45 |
+ NOTE: This will now be an object instead of an associative array. To get |
|
| 46 |
+ an associative array, you will need to cast it as such: |
|
| 47 |
+*/ |
|
| 48 |
+ |
|
| 49 |
+$decoded_array = (array) $decoded; |
|
| 50 |
+ |
|
| 51 |
+/** |
|
| 52 |
+ * You can add a leeway to account for when there is a clock skew times between |
|
| 53 |
+ * the signing and verifying servers. It is recommended that this leeway should |
|
| 54 |
+ * not be bigger than a few minutes. |
|
| 55 |
+ * |
|
| 56 |
+ * Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef |
|
| 57 |
+ */ |
|
| 58 |
+JWT::$leeway = 60; // $leeway in seconds |
|
| 59 |
+$decoded = JWT::decode($jwt, $key, array('HS256'));
|
|
| 60 |
+ |
|
| 61 |
+?> |
|
| 62 |
+``` |
|
| 63 |
+Example with RS256 (openssl) |
|
| 64 |
+---------------------------- |
|
| 65 |
+```php |
|
| 66 |
+<?php |
|
| 67 |
+use \Firebase\JWT\JWT; |
|
| 68 |
+ |
|
| 69 |
+$privateKey = <<<EOD |
|
| 70 |
+-----BEGIN RSA PRIVATE KEY----- |
|
| 71 |
+MIICXAIBAAKBgQC8kGa1pSjbSYZVebtTRBLxBz5H4i2p/llLCrEeQhta5kaQu/Rn |
|
| 72 |
+vuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t0tyazyZ8JXw+KgXTxldMPEL9 |
|
| 73 |
+5+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4ehde/zUxo6UvS7UrBQIDAQAB |
|
| 74 |
+AoGAb/MXV46XxCFRxNuB8LyAtmLDgi/xRnTAlMHjSACddwkyKem8//8eZtw9fzxz |
|
| 75 |
+bWZ/1/doQOuHBGYZU8aDzzj59FZ78dyzNFoF91hbvZKkg+6wGyd/LrGVEB+Xre0J |
|
| 76 |
+Nil0GReM2AHDNZUYRv+HYJPIOrB0CRczLQsgFJ8K6aAD6F0CQQDzbpjYdx10qgK1 |
|
| 77 |
+cP59UHiHjPZYC0loEsk7s+hUmT3QHerAQJMZWC11Qrn2N+ybwwNblDKv+s5qgMQ5 |
|
| 78 |
+5tNoQ9IfAkEAxkyffU6ythpg/H0Ixe1I2rd0GbF05biIzO/i77Det3n4YsJVlDck |
|
| 79 |
+ZkcvY3SK2iRIL4c9yY6hlIhs+K9wXTtGWwJBAO9Dskl48mO7woPR9uD22jDpNSwe |
|
| 80 |
+k90OMepTjzSvlhjbfuPN1IdhqvSJTDychRwn1kIJ7LQZgQ8fVz9OCFZ/6qMCQGOb |
|
| 81 |
+qaGwHmUK6xzpUbbacnYrIM6nLSkXgOAwv7XXCojvY614ILTK3iXiLBOxPu5Eu13k |
|
| 82 |
+eUz9sHyD6vkgZzjtxXECQAkp4Xerf5TGfQXGXhxIX52yH+N2LtujCdkQZjXAsGdm |
|
| 83 |
+B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM= |
|
| 84 |
+-----END RSA PRIVATE KEY----- |
|
| 85 |
+EOD; |
|
| 86 |
+ |
|
| 87 |
+$publicKey = <<<EOD |
|
| 88 |
+-----BEGIN PUBLIC KEY----- |
|
| 89 |
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H |
|
| 90 |
+4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t |
|
| 91 |
+0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4 |
|
| 92 |
+ehde/zUxo6UvS7UrBQIDAQAB |
|
| 93 |
+-----END PUBLIC KEY----- |
|
| 94 |
+EOD; |
|
| 95 |
+ |
|
| 96 |
+$payload = array( |
|
| 97 |
+ "iss" => "example.org", |
|
| 98 |
+ "aud" => "example.com", |
|
| 99 |
+ "iat" => 1356999524, |
|
| 100 |
+ "nbf" => 1357000000 |
|
| 101 |
+); |
|
| 102 |
+ |
|
| 103 |
+$jwt = JWT::encode($payload, $privateKey, 'RS256'); |
|
| 104 |
+echo "Encode:\n" . print_r($jwt, true) . "\n"; |
|
| 105 |
+ |
|
| 106 |
+$decoded = JWT::decode($jwt, $publicKey, array('RS256'));
|
|
| 107 |
+ |
|
| 108 |
+/* |
|
| 109 |
+ NOTE: This will now be an object instead of an associative array. To get |
|
| 110 |
+ an associative array, you will need to cast it as such: |
|
| 111 |
+*/ |
|
| 112 |
+ |
|
| 113 |
+$decoded_array = (array) $decoded; |
|
| 114 |
+echo "Decode:\n" . print_r($decoded_array, true) . "\n"; |
|
| 115 |
+?> |
|
| 116 |
+``` |
|
| 117 |
+ |
|
| 118 |
+Changelog |
|
| 119 |
+--------- |
|
| 120 |
+ |
|
| 121 |
+#### 5.0.0 / 2017-06-26 |
|
| 122 |
+- Support RS384 and RS512. |
|
| 123 |
+ See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)! |
|
| 124 |
+- Add an example for RS256 openssl. |
|
| 125 |
+ See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)! |
|
| 126 |
+- Detect invalid Base64 encoding in signature. |
|
| 127 |
+ See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)! |
|
| 128 |
+- Update `JWT::verify` to handle OpenSSL errors. |
|
| 129 |
+ See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)! |
|
| 130 |
+- Add `array` type hinting to `decode` method |
|
| 131 |
+ See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)! |
|
| 132 |
+- Add all JSON error types. |
|
| 133 |
+ See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)! |
|
| 134 |
+- Bugfix 'kid' not in given key list. |
|
| 135 |
+ See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)! |
|
| 136 |
+- Miscellaneous cleanup, documentation and test fixes. |
|
| 137 |
+ See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115), |
|
| 138 |
+ [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and |
|
| 139 |
+ [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman), |
|
| 140 |
+ [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)! |
|
| 141 |
+ |
|
| 142 |
+#### 4.0.0 / 2016-07-17 |
|
| 143 |
+- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! |
|
| 144 |
+- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! |
|
| 145 |
+- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! |
|
| 146 |
+- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! |
|
| 147 |
+ |
|
| 148 |
+#### 3.0.0 / 2015-07-22 |
|
| 149 |
+- Minimum PHP version updated from `5.2.0` to `5.3.0`. |
|
| 150 |
+- Add `\Firebase\JWT` namespace. See |
|
| 151 |
+[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to |
|
| 152 |
+[@Dashron](https://github.com/Dashron)! |
|
| 153 |
+- Require a non-empty key to decode and verify a JWT. See |
|
| 154 |
+[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to |
|
| 155 |
+[@sjones608](https://github.com/sjones608)! |
|
| 156 |
+- Cleaner documentation blocks in the code. See |
|
| 157 |
+[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to |
|
| 158 |
+[@johanderuijter](https://github.com/johanderuijter)! |
|
| 159 |
+ |
|
| 160 |
+#### 2.2.0 / 2015-06-22 |
|
| 161 |
+- Add support for adding custom, optional JWT headers to `JWT::encode()`. See |
|
| 162 |
+[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to |
|
| 163 |
+[@mcocaro](https://github.com/mcocaro)! |
|
| 164 |
+ |
|
| 165 |
+#### 2.1.0 / 2015-05-20 |
|
| 166 |
+- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew |
|
| 167 |
+between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)! |
|
| 168 |
+- Add support for passing an object implementing the `ArrayAccess` interface for |
|
| 169 |
+`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)! |
|
| 170 |
+ |
|
| 171 |
+#### 2.0.0 / 2015-04-01 |
|
| 172 |
+- **Note**: It is strongly recommended that you update to > v2.0.0 to address |
|
| 173 |
+ known security vulnerabilities in prior versions when both symmetric and |
|
| 174 |
+ asymmetric keys are used together. |
|
| 175 |
+- Update signature for `JWT::decode(...)` to require an array of supported |
|
| 176 |
+ algorithms to use when verifying token signatures. |
|
| 177 |
+ |
|
| 178 |
+ |
|
| 179 |
+Tests |
|
| 180 |
+----- |
|
| 181 |
+Run the tests using phpunit: |
|
| 182 |
+ |
|
| 183 |
+```bash |
|
| 184 |
+$ pear install PHPUnit |
|
| 185 |
+$ phpunit --configuration phpunit.xml.dist |
|
| 186 |
+PHPUnit 3.7.10 by Sebastian Bergmann. |
|
| 187 |
+..... |
|
| 188 |
+Time: 0 seconds, Memory: 2.50Mb |
|
| 189 |
+OK (5 tests, 5 assertions) |
|
| 190 |
+``` |
|
| 191 |
+ |
|
| 192 |
+New Lines in private keys |
|
| 193 |
+----- |
|
| 194 |
+ |
|
| 195 |
+If your private key contains `\n` characters, be sure to wrap it in double quotes `""` |
|
| 196 |
+and not single quotes `''` in order to properly interpret the escaped characters. |
|
| 197 |
+ |
|
| 198 |
+License |
|
| 199 |
+------- |
|
| 200 |
+[3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause). |