Skip to content

Commit c2e6c8b

Browse files
authored
Merge pull request #8 from adhocore/develop
Support php5.5
2 parents 3cbbf06 + 7eb47d9 commit c2e6c8b

7 files changed

+70
-38
lines changed

.travis.yml

+5
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@ git:
99

1010
language: php
1111
php:
12+
- 5.5
13+
- 5.6
1214
- 7.0
1315
- 7.1
1416
- 7.2
1517

1618
install:
1719
- composer install --prefer-dist
1820

21+
before_script:
22+
- for P in src tests; do find $P -type f -name '*.php' -exec php -l {} \;; done
23+
1924
script:
2025
- vendor/bin/phpunit --coverage-text --coverage-clover=coverage.xml
2126

composer.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "adhocore/jwt",
3-
"description": "Ultra lightweight JSON web token (JWT) library for PHP7.",
3+
"description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.",
44
"type": "library",
55
"keywords": [
66
"jwt", "jwt-php", "auth", "json-web-token", "token"
@@ -15,17 +15,18 @@
1515
"autoload": {
1616
"psr-4": {
1717
"Ahc\\Jwt\\": "src/"
18-
}
18+
},
19+
"files": ["src/functions.php"]
1920
},
2021
"autoload-dev": {
2122
"psr-4": {
2223
"Ahc\\Jwt\\Test\\": "tests/"
2324
}
2425
},
2526
"require": {
26-
"php": ">=7.0"
27+
"php": ">=5.5"
2728
},
2829
"require-dev": {
29-
"phpunit/phpunit": "^6.0.0"
30+
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5"
3031
}
3132
}

readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
99

1010

11-
- Lightweight JSON Web Token (JWT) library for PHP7.
11+
- Lightweight JSON Web Token (JWT) library for PHP5.5 or newer.
1212

1313
## Installation
1414
```

src/JWT.php

+11-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Ahc\Jwt;
44

55
/**
6-
* JSON Web Token (JWT) implementation in PHP7.
6+
* JSON Web Token (JWT) implementation in PHP5.5+.
77
*
88
* @author Jitendra Adhikari <[email protected]>
99
* @license MIT
@@ -68,7 +68,7 @@ class JWT
6868
* @param int $leeway Leeway for clock skew. Shouldnot be more than 2 minutes (120s).
6969
* @param string $pass The passphrase (only for RS* algos).
7070
*/
71-
public function __construct($key, string $algo = 'HS256', int $maxAge = 3600, int $leeway = 0, string $pass = null)
71+
public function __construct($key, $algo = 'HS256', $maxAge = 3600, $leeway = 0, $pass = null)
7272
{
7373
$this->validateConfig($key, $algo, $maxAge, $leeway);
7474

@@ -91,7 +91,7 @@ public function __construct($key, string $algo = 'HS256', int $maxAge = 3600, in
9191
*
9292
* @return self
9393
*/
94-
public function registerKeys(array $keys): self
94+
public function registerKeys(array $keys)
9595
{
9696
$this->keys = \array_merge($this->keys, $keys);
9797

@@ -106,14 +106,14 @@ public function registerKeys(array $keys): self
106106
*
107107
* @return string URL safe JWT token.
108108
*/
109-
public function encode(array $payload, array $header = []) : string
109+
public function encode(array $payload, array $header = [])
110110
{
111111
$header = ['typ' => 'JWT', 'alg' => $this->algo] + $header;
112112

113113
$this->validateKid($header);
114114

115115
if (!isset($payload['iat']) && !isset($payload['exp'])) {
116-
$payload['exp'] = ($this->timestamp ?? \time()) + $this->maxAge;
116+
$payload['exp'] = ($this->timestamp ?: \time()) + $this->maxAge;
117117
}
118118

119119
$header = $this->urlSafeEncode($header);
@@ -130,7 +130,7 @@ public function encode(array $payload, array $header = []) : string
130130
*
131131
* @return array
132132
*/
133-
public function decode(string $token) : array
133+
public function decode($token)
134134
{
135135
if (\substr_count($token, '.') < 2) {
136136
throw new JWTException('Invalid token: Incomplete segments', static::ERROR_TOKEN_INVALID);
@@ -156,7 +156,7 @@ public function decode(string $token) : array
156156
*
157157
* @param int|null $timestamp
158158
*/
159-
public function setTestTimestamp(int $timestamp = null) : JWT
159+
public function setTestTimestamp($timestamp = null)
160160
{
161161
$this->timestamp = $timestamp;
162162

@@ -170,7 +170,7 @@ public function setTestTimestamp(int $timestamp = null) : JWT
170170
*
171171
* @return string
172172
*/
173-
protected function sign(string $input) : string
173+
protected function sign($input)
174174
{
175175
// HMAC SHA.
176176
if (\substr($this->algo, 0, 2) === 'HS') {
@@ -194,7 +194,7 @@ protected function sign(string $input) : string
194194
*
195195
* @return bool
196196
*/
197-
protected function verify(string $input, string $signature) : bool
197+
protected function verify($input, $signature)
198198
{
199199
$algo = $this->algos[$this->algo];
200200

@@ -221,7 +221,7 @@ protected function verify(string $input, string $signature) : bool
221221
*
222222
* @return string
223223
*/
224-
protected function urlSafeEncode($data) : string
224+
protected function urlSafeEncode($data)
225225
{
226226
if (\is_array($data)) {
227227
$data = \json_encode($data, JSON_UNESCAPED_SLASHES);
@@ -241,7 +241,7 @@ protected function urlSafeEncode($data) : string
241241
*
242242
* @return array|\stdClass|string
243243
*/
244-
protected function urlSafeDecode(string $data, bool $asJson = true)
244+
protected function urlSafeDecode($data, $asJson = true)
245245
{
246246
if (!$asJson) {
247247
return \base64_decode(\strtr($data, '-_', '+/'));

src/ValidatesJWT.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ trait ValidatesJWT
1717
*
1818
* @codeCoverageIgnore
1919
*/
20-
protected function validateConfig($key, string $algo, int $maxAge, int $leeway)
20+
protected function validateConfig($key, $algo, $maxAge, $leeway)
2121
{
2222
if (empty($key)) {
2323
throw new JWTException('Signing key cannot be empty', static::ERROR_KEY_EMPTY);
@@ -71,7 +71,7 @@ protected function validateKid(array $header)
7171
*/
7272
protected function validateTimestamps(array $payload)
7373
{
74-
$timestamp = $this->timestamp ?? \time();
74+
$timestamp = $this->timestamp ?: \time();
7575
$checks = [
7676
['exp', $this->leeway /* */ , static::ERROR_TOKEN_EXPIRED, 'Expired'],
7777
['iat', $this->maxAge - $this->leeway, static::ERROR_TOKEN_EXPIRED, 'Expired'],
@@ -100,7 +100,7 @@ protected function validateKey()
100100
$key = 'file://' . $key;
101101
}
102102

103-
$this->key = \openssl_get_privatekey($key, $this->passphrase ?? '');
103+
$this->key = \openssl_get_privatekey($key, $this->passphrase ?: '');
104104
}
105105

106106
if (!\is_resource($this->key)) {

src/functions.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
// @codeCoverageIgnoreStart
4+
if (!\function_exists('hash_equals')) {
5+
// PHP5.5 compat.
6+
// @see http://php.net/manual/en/function.hash-equals.php#115635
7+
function hash_equals($str1, $str2)
8+
{
9+
if (\strlen($str1) !== \strlen($str2)) {
10+
return false;
11+
}
12+
13+
$ret = 0;
14+
$res = $str1 ^ $str2;
15+
16+
for ($i = \strlen($res) - 1; $i >= 0; $i--) {
17+
$ret |= ord($res[$i]);
18+
}
19+
20+
return !$ret;
21+
}
22+
}
23+
// @codeCoverageIgnoreEnd

tests/JWTTest.php

+22-19
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
namespace Ahc\Jwt\Test;
44

55
use Ahc\Jwt\JWT;
6-
use Ahc\Jwt\JWTException;
76

87
/** @coversDefaultClass \Ahc\Jwt\JWT */
98
class JWTTest extends \PHPUnit\Framework\TestCase
109
{
1110
/** @dataProvider data1 */
12-
public function test_decode_encoded_token(string $key, string $algo, int $age, int $leeway, array $payload, array $header = [])
11+
public function test_decode_encoded_token($key, $algo, $age, $leeway, array $payload, array $header = [])
1312
{
1413
$jwt = new JWT($key, $algo, $age, $leeway);
1514
$token = $jwt->encode($payload, $header);
@@ -26,26 +25,28 @@ public function test_decode_encoded_token(string $key, string $algo, int $age, i
2625
$this->assertSame($payload, $decoded);
2726
}
2827

28+
/**
29+
* @expectedException \Ahc\Jwt\JWTException
30+
*/
2931
public function test_json_fail()
3032
{
31-
$this->expectException(JWTException::class);
32-
3333
$jwt = new JWT('very^secre7');
3434

3535
try {
36-
$jwt->encode([random_bytes(10)]);
36+
$jwt->encode([base64_decode('mF6u28o4K2cD3w==')]);
3737
} catch (\Exception $e) {
3838
$this->assertSame($e->getCode(), JWT::ERROR_JSON_FAILED, $e->getMessage());
3939

4040
throw $e;
4141
}
4242
}
4343

44-
/** @dataProvider data2 */
45-
public function test_decode_fail(string $key, string $algo, int $age, int $leeway, int $offset, int $error, $token)
44+
/**
45+
* @dataProvider data2
46+
* @expectedException \Ahc\Jwt\JWTException
47+
*/
48+
public function test_decode_fail($key, $algo, $age, $leeway, $offset, $error, $token)
4649
{
47-
$this->expectException(JWTException::class);
48-
4950
$jwt = new JWT($key, $algo, $age, $leeway);
5051
$token = is_string($token) ? $token : $jwt->encode($token);
5152

@@ -63,7 +64,7 @@ public function test_decode_fail(string $key, string $algo, int $age, int $leewa
6364
}
6465

6566
/** @dataProvider data1 */
66-
public function test_rs_decode_encoded(string $key, string $algo, int $age, int $leeway, array $payload, array $header = [])
67+
public function test_rs_decode_encoded($key, $algo, $age, $leeway, array $payload, array $header = [])
6768
{
6869
$key = __DIR__ . '/stubs/priv.key';
6970
$jwt = new JWT($key, str_replace('HS', 'RS', $algo), $age, $leeway);
@@ -81,11 +82,12 @@ public function test_rs_decode_encoded(string $key, string $algo, int $age, int
8182
$this->assertSame($payload, $decoded);
8283
}
8384

84-
/** @dataProvider data3 */
85-
public function test_rs_invalid_key(string $method, string $key, $arg)
85+
/**
86+
* @dataProvider data3
87+
* @expectedException \Ahc\Jwt\JWTException
88+
*/
89+
public function test_rs_invalid_key($method, $key, $arg)
8690
{
87-
$this->expectException(JWTException::class);
88-
8991
$jwt = new JWT($key, 'RS256');
9092

9193
try {
@@ -109,19 +111,20 @@ public function test_kid()
109111
return $jwt;
110112
}
111113

114+
/**
115+
* @expectedException \Ahc\Jwt\JWTException
116+
* @expectedExceptionMessage Invalid token: Unknown key ID
117+
*/
112118
public function test_kid_invalid()
113119
{
114120
// keys can be sent as array too
115121
$jwt = new JWT(['key1' => 'secret1', 'key2' => 'secret2'], 'HS256');
116122

117-
$this->expectException(JWTException::class);
118-
$this->expectExceptionMessage('Invalid token: Unknown key ID');
119-
120123
// Use key3
121124
$jwt->encode(['a' => 1, 'exp' => time() + 1000], ['kid' => 'key3']);
122125
}
123126

124-
public function data1() : array
127+
public function data1()
125128
{
126129
return [
127130
['secret', 'HS256', rand(10, 1000), rand(1, 10), [
@@ -152,7 +155,7 @@ public function data1() : array
152155
];
153156
}
154157

155-
public function data2() : array
158+
public function data2()
156159
{
157160
return [
158161
['topsecret', 'HS256', 5, 0, 0, JWT::ERROR_TOKEN_INVALID, 'a.b'],

0 commit comments

Comments
 (0)