Skip to content

Commit 093da8b

Browse files
authored
Merge pull request #1 from firebase/main
up
2 parents 11ce26b + 92aa12d commit 093da8b

32 files changed

+1369
-390
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: 128 additions & 15 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,8 +80,8 @@ 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-----
@@ -120,17 +125,17 @@ ZwIDAQAB
120125
-----END PUBLIC KEY-----
121126
EOD;
122127

123-
$token = array(
128+
$payload = array(
124129
"iss" => "example.org",
125130
"aud" => "example.com",
126131
"iat" => 1356999524,
127132
"nbf" => 1357000000
128133
);
129134

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

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

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

140145
$decoded_array = (array) $decoded;
141146
echo "Decode:\n" . print_r($decoded_array, true) . "\n";
142-
?>
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);
143247
```
144248

145249
Changelog
146250
---------
147251

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+
148261
#### 5.0.0 / 2017-06-26
149262
- Support RS384 and RS512.
150263
See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)!

composer.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
"name": "firebase/php-jwt",
33
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
44
"homepage": "https://github.com/firebase/php-jwt",
5+
"keywords": [
6+
"php",
7+
"jwt"
8+
],
59
"authors": [
610
{
711
"name": "Neuman Vong",
@@ -16,14 +20,17 @@
1620
],
1721
"license": "BSD-3-Clause",
1822
"require": {
19-
"php": ">=5.3.0"
23+
"php": "^8.0"
24+
},
25+
"suggest": {
26+
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
2027
},
2128
"autoload": {
2229
"psr-4": {
2330
"Firebase\\JWT\\": "src"
2431
}
2532
},
2633
"require-dev": {
27-
"phpunit/phpunit": " 4.8.35"
34+
"phpunit/phpunit": "^9.5"
2835
}
2936
}

phpstan.neon.dist

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
parameters:
2+
level: 7
3+
paths:
4+
- src
5+
treatPhpDocTypesAsCertain: false

phpunit.xml.dist

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
convertWarningsToExceptions="true"
99
processIsolation="false"
1010
stopOnFailure="false"
11-
syntaxCheck="false"
1211
bootstrap="tests/bootstrap.php"
1312
>
1413
<testsuites>

0 commit comments

Comments
 (0)