Skip to content

Commit e0d0f70

Browse files
authored
Merge pull request #1 from tekintian/master
update
2 parents dfe1fba + 093da8b commit e0d0f70

32 files changed

+1401
-407
lines changed

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
/.gitignore export-ignore
66
/.travis.yml export-ignore
77
/phpunit.xml.dist export-ignore
8-
/run-tests.sh export-ignore
8+
/.github export-ignore

.github/actions/entrypoint.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/sh -l
2+
3+
apt-get update && \
4+
apt-get install -y --no-install-recommends \
5+
git \
6+
zip \
7+
curl \
8+
ca-certificates \
9+
unzip \
10+
wget
11+
12+
curl --silent --show-error https://getcomposer.org/installer | php
13+
php composer.phar self-update
14+
15+
echo "---Installing dependencies ---"
16+
17+
# Add compatiblity for libsodium with older versions of PHP
18+
php composer.phar require --dev --with-dependencies paragonie/sodium_compat
19+
20+
echo "---Running unit tests ---"
21+
vendor/bin/phpunit

.github/workflows/tests.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Test Suite
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
php: [ "8.0", "8.1"]
14+
name: PHP ${{matrix.php }} Unit Test
15+
steps:
16+
- uses: actions/checkout@v2
17+
- name: Setup PHP
18+
uses: shivammathur/setup-php@v2
19+
with:
20+
php-version: ${{ matrix.php }}
21+
- name: Install Dependencies
22+
uses: nick-invision/retry@v1
23+
with:
24+
timeout_minutes: 10
25+
max_attempts: 3
26+
command: composer install
27+
- name: Run Script
28+
run: vendor/bin/phpunit
29+
30+
style:
31+
runs-on: ubuntu-latest
32+
name: PHP Style Check
33+
steps:
34+
- uses: actions/checkout@v2
35+
- name: Setup PHP
36+
uses: shivammathur/setup-php@v2
37+
with:
38+
php-version: "8.0"
39+
- name: Run Script
40+
run: |
41+
composer require friendsofphp/php-cs-fixer
42+
vendor/bin/php-cs-fixer fix --diff --dry-run .
43+
vendor/bin/php-cs-fixer fix --rules=native_function_invocation --allow-risky=yes --diff src
44+
45+
staticanalysis:
46+
runs-on: ubuntu-latest
47+
name: PHPStan Static Analysis
48+
steps:
49+
- uses: actions/checkout@v2
50+
- name: Install PHP
51+
uses: shivammathur/setup-php@v2
52+
with:
53+
php-version: '8.0'
54+
- name: Run Script
55+
run: |
56+
composer global require phpstan/phpstan
57+
~/.composer/vendor/bin/phpstan analyse

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ phpunit.phar
33
phpunit.phar.asc
44
composer.phar
55
composer.lock
6+
.phpunit.result.cache

.travis.yml

Lines changed: 0 additions & 19 deletions
This file was deleted.

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ modification, are permitted provided that the following conditions are met:
1313
disclaimer in the documentation and/or other materials provided
1414
with the distribution.
1515

16-
* Neither the name of Neuman Vong nor the names of other
16+
* Neither the name of the copyright holder nor the names of other
1717
contributors may be used to endorse or promote products derived
1818
from this software without specific prior written permission.
1919

README.md

Lines changed: 160 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Build Status](https://travis-ci.org/firebase/php-jwt.png?branch=master)](https://travis-ci.org/firebase/php-jwt)
1+
![Build Status](https://github.com/firebase/php-jwt/actions/workflows/tests.yml/badge.svg)
22
[![Latest Stable Version](https://poser.pugx.org/firebase/php-jwt/v/stable)](https://packagist.org/packages/firebase/php-jwt)
33
[![Total Downloads](https://poser.pugx.org/firebase/php-jwt/downloads)](https://packagist.org/packages/firebase/php-jwt)
44
[![License](https://poser.pugx.org/firebase/php-jwt/license)](https://packagist.org/packages/firebase/php-jwt)
@@ -16,14 +16,21 @@ Use composer to manage your dependencies and download PHP-JWT:
1616
composer require firebase/php-jwt
1717
```
1818

19+
Optionally, install the `paragonie/sodium_compat` package from composer if your
20+
php is < 7.2 or does not have libsodium installed:
21+
22+
```bash
23+
composer require paragonie/sodium_compat
24+
```
25+
1926
Example
2027
-------
2128
```php
22-
<?php
23-
use \Firebase\JWT\JWT;
29+
use Firebase\JWT\JWT;
30+
use Firebase\JWT\Key;
2431

2532
$key = "example_key";
26-
$token = array(
33+
$payload = array(
2734
"iss" => "http://example.org",
2835
"aud" => "http://example.com",
2936
"iat" => 1356999524,
@@ -36,8 +43,8 @@ $token = array(
3643
* https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40
3744
* for a list of spec-compliant algorithms.
3845
*/
39-
$jwt = JWT::encode($token, $key);
40-
$decoded = JWT::decode($jwt, $key, array('HS256'));
46+
$jwt = JWT::encode($payload, $key, 'HS256');
47+
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
4148

4249
print_r($decoded);
4350

@@ -56,9 +63,7 @@ $decoded_array = (array) $decoded;
5663
* Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef
5764
*/
5865
JWT::$leeway = 60; // $leeway in seconds
59-
$decoded = JWT::decode($jwt, $key, array('HS256'));
60-
61-
?>
66+
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
6267
```
6368
Example with RS256 (openssl)
6469

@@ -75,47 +80,62 @@ openssl rsa -in id_rsa -pubout > id_rsa_pub.key
7580

7681
----------------------------
7782
```php
78-
<?php
79-
use \Firebase\JWT\JWT;
83+
use Firebase\JWT\JWT;
84+
use Firebase\JWT\Key;
8085

8186
$privateKey = <<<EOD
8287
-----BEGIN RSA PRIVATE KEY-----
83-
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
96113
-----END RSA PRIVATE KEY-----
97114
EOD;
98115

99116
$publicKey = <<<EOD
100117
-----BEGIN PUBLIC KEY-----
101-
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H
102-
4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t
103-
0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4
104-
ehde/zUxo6UvS7UrBQIDAQAB
118+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArcnsWs90Uc6iU90FPomb
119+
aR8SuAFNZrXuKVjVu8VyYAZgKOBtV/bxnW/55wlfVpGX00BHCZeqtCUpjiGC1ny5
120+
DPx29UuF/Kgi9FjceF/P8dPukED6JURclOoC/xwLPJz327NV1RJAC2j4C5OphVzB
121+
JkOfWiu/7xkQH2sF1ec7VR83/kxenV67iHfwsVS8gFqzxaEdiMXCABUzGn2xhReK
122+
NGJpJxTsI7KpafQsuVKAChptngKCjr+YCKmRrjcX2bCJ6Pskai6G8JUkKJS/pAbZ
123+
pIQ6uWuKVhhFxXdjSUyj0Bjsoj7g1tQqZB2LPuzwjD39JZnRg9sPyZ32DBlX0tuY
124+
ZwIDAQAB
105125
-----END PUBLIC KEY-----
106126
EOD;
107127

108-
$token = array(
128+
$payload = array(
109129
"iss" => "example.org",
110130
"aud" => "example.com",
111131
"iat" => 1356999524,
112132
"nbf" => 1357000000
113133
);
114134

115-
$jwt = JWT::encode($token, $privateKey, 'RS256');
135+
$jwt = JWT::encode($payload, $privateKey, 'RS256');
116136
echo "Encode:\n" . print_r($jwt, true) . "\n";
117137

118-
$decoded = JWT::decode($jwt, $publicKey, array('RS256'));
138+
$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256'));
119139

120140
/*
121141
NOTE: This will now be an object instead of an associative array. To get
@@ -124,12 +144,120 @@ $decoded = JWT::decode($jwt, $publicKey, array('RS256'));
124144

125145
$decoded_array = (array) $decoded;
126146
echo "Decode:\n" . print_r($decoded_array, true) . "\n";
127-
?>
147+
```
148+
149+
Example with a passphrase
150+
-------------------------
151+
152+
```php
153+
use Firebase\JWT\JWT;
154+
use Firebase\JWT\Key;
155+
156+
// Your passphrase
157+
$passphrase = '[YOUR_PASSPHRASE]';
158+
159+
// Your private key file with passphrase
160+
// Can be generated with "ssh-keygen -t rsa -m pem"
161+
$privateKeyFile = '/path/to/key-with-passphrase.pem';
162+
163+
// Create a private key of type "resource"
164+
$privateKey = openssl_pkey_get_private(
165+
file_get_contents($privateKeyFile),
166+
$passphrase
167+
);
168+
169+
$payload = array(
170+
"iss" => "example.org",
171+
"aud" => "example.com",
172+
"iat" => 1356999524,
173+
"nbf" => 1357000000
174+
);
175+
176+
$jwt = JWT::encode($payload, $privateKey, 'RS256');
177+
echo "Encode:\n" . print_r($jwt, true) . "\n";
178+
179+
// Get public key from the private key, or pull from from a file.
180+
$publicKey = openssl_pkey_get_details($privateKey)['key'];
181+
182+
$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256'));
183+
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
184+
```
185+
186+
Example with EdDSA (libsodium and Ed25519 signature)
187+
----------------------------
188+
```php
189+
use Firebase\JWT\JWT;
190+
use Firebase\JWT\Key;
191+
192+
// Public and private keys are expected to be Base64 encoded. The last
193+
// non-empty line is used so that keys can be generated with
194+
// sodium_crypto_sign_keypair(). The secret keys generated by other tools may
195+
// need to be adjusted to match the input expected by libsodium.
196+
197+
$keyPair = sodium_crypto_sign_keypair();
198+
199+
$privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair));
200+
201+
$publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));
202+
203+
$payload = array(
204+
"iss" => "example.org",
205+
"aud" => "example.com",
206+
"iat" => 1356999524,
207+
"nbf" => 1357000000
208+
);
209+
210+
$jwt = JWT::encode($payload, $privateKey, 'EdDSA');
211+
echo "Encode:\n" . print_r($jwt, true) . "\n";
212+
213+
$decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA'));
214+
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
215+
````
216+
217+
Using JWKs
218+
----------
219+
220+
```php
221+
use Firebase\JWT\JWK;
222+
use Firebase\JWT\JWT;
223+
224+
// Set of keys. The "keys" key is required. For example, the JSON response to
225+
// this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
226+
$jwks = ['keys' => []];
227+
228+
// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
229+
// objects. Pass this as the second parameter to JWT::decode.
230+
JWT::decode($payload, JWK::parseKeySet($jwks));
231+
```
232+
233+
Miscellaneous
234+
-------------
235+
236+
#### Casting to array
237+
238+
The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays
239+
instead, you can do the following:
240+
241+
```php
242+
// return type is stdClass
243+
$decoded = JWT::decode($payload, $keys);
244+
245+
// cast to array
246+
$decoded = json_decode(json_encode($decoded), true);
128247
```
129248

130249
Changelog
131250
---------
132251

252+
#### 6.0.0 / 2022-01-24
253+
254+
- **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information.
255+
- New Key object to prevent key/algorithm type confusion (#365)
256+
- Add JWK support (#273)
257+
- Add ES256 support (#256)
258+
- Add ES384 support (#324)
259+
- Add Ed25519 support (#343)
260+
133261
#### 5.0.0 / 2017-06-26
134262
- Support RS384 and RS512.
135263
See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)!

0 commit comments

Comments
 (0)